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 tree current_function_decl
;
79 extern FILE *asm_out_file
;
81 /* Enumeration for all of the relational tests, so that we can build
82 arrays indexed by the test type, and not worry about the order
99 /* Global variables for machine-dependent things. */
101 /* Threshold for data being put into the small data/bss area, instead
102 of the normal data area (references to the small data/bss area take
103 1 instruction, and use the global pointer, references to the normal
104 data area takes 2 instructions). */
105 int mips_section_threshold
= -1;
107 /* Count the number of .file directives, so that .loc is up to date. */
108 int num_source_filenames
= 0;
110 /* Count the number of sdb related labels are generated (to find block
111 start and end boundaries). */
112 int sdb_label_count
= 0;
114 /* Next label # for each statment for Silicon Graphics IRIS systems. */
117 /* Non-zero if inside of a function, because the stupid MIPS asm can't
118 handle .files inside of functions. */
119 int inside_function
= 0;
121 /* Files to separate the text and the data output, so that all of the data
122 can be emitted before the text, which will mean that the assembler will
123 generate smaller code, based on the global pointer. */
124 FILE *asm_out_data_file
;
125 FILE *asm_out_text_file
;
127 /* Linked list of all externals that are to be emitted when optimizing
128 for the global pointer if they haven't been declared by the end of
129 the program with an appropriate .comm or initialization. */
132 struct extern_list
*next
; /* next external */
133 char *name
; /* name of the external */
134 int size
; /* size in bytes */
137 /* Name of the file containing the current function. */
138 char *current_function_file
= "";
140 /* Warning given that Mips ECOFF can't support changing files
141 within a function. */
142 int file_in_function_warning
= FALSE
;
144 /* Whether to suppress issuing .loc's because the user attempted
145 to change the filename within a function. */
146 int ignore_line_number
= FALSE
;
148 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
154 /* The next branch instruction is a branch likely, not branch normal. */
155 int mips_branch_likely
;
157 /* Count of delay slots and how many are filled. */
158 int dslots_load_total
;
159 int dslots_load_filled
;
160 int dslots_jump_total
;
161 int dslots_jump_filled
;
163 /* # of nops needed by previous insn */
164 int dslots_number_nops
;
166 /* Number of 1/2/3 word references to data items (ie, not jal's). */
169 /* registers to check for load delay */
170 rtx mips_load_reg
, mips_load_reg2
, mips_load_reg3
, mips_load_reg4
;
172 /* Cached operands, and operator to compare for use in set/branch on
176 /* what type of branch to use */
177 enum cmp_type branch_type
;
179 /* Number of previously seen half-pic pointers and references. */
180 static int prev_half_pic_ptrs
= 0;
181 static int prev_half_pic_refs
= 0;
183 /* which cpu are we scheduling for */
184 enum processor_type mips_cpu
;
186 /* which instruction set architecture to use. */
189 /* Strings to hold which cpu and instruction set architecture to use. */
190 char *mips_cpu_string
; /* for -mcpu=<xxx> */
191 char *mips_isa_string
; /* for -mips{1,2,3} */
193 /* Array to RTX class classification. At present, we care about
194 whether the operator is an add-type operator, or a divide/modulus,
195 and if divide/modulus, whether it is unsigned. This is for the
197 char mips_rtx_classify
[NUM_RTX_CODE
];
199 /* Array giving truth value on whether or not a given hard register
200 can support a given mode. */
201 char mips_hard_regno_mode_ok
[(int)MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
203 /* Current frame information calculated by compute_frame_size. */
204 struct mips_frame_info current_frame_info
;
206 /* Zero structure to initialize current_frame_info. */
207 struct mips_frame_info zero_frame_info
;
209 /* Temporary filename used to buffer .text until end of program
211 static char *temp_filename
;
213 /* List of all MIPS punctuation characters used by print_operand. */
214 char mips_print_operand_punct
[256];
216 /* Map GCC register number to debugger register number. */
217 int mips_dbx_regno
[FIRST_PSEUDO_REGISTER
];
219 /* Buffer to use to enclose a load/store operation with %{ %} to
220 turn on .set volatile. */
221 static char volatile_buffer
[60];
223 /* Hardware names for the registers. If -mrnames is used, this
224 will be overwritten with mips_sw_reg_names. */
226 char mips_reg_names
[][8] =
228 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
229 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
230 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
231 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
232 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
233 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
234 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
235 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
239 /* Mips software names for the registers, used to overwrite the
240 mips_reg_names array. */
242 char mips_sw_reg_names
[][8] =
244 "$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
245 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
246 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
247 "t8", "t9", "k0", "k1", "gp", "sp", "$fp", "ra",
248 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
249 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
250 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
251 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
255 /* Map hard register number to register class */
256 enum reg_class mips_regno_to_class
[] =
258 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
259 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
260 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
261 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
262 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
263 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
264 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
265 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
266 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
267 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
268 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
269 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
270 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
271 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
272 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
273 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
274 HI_REG
, LO_REG
, ST_REGS
277 /* Map register constraint character to register class. */
278 enum reg_class mips_char_to_class
[256] =
280 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
281 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
282 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
283 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
284 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
285 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
286 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
287 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
288 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
289 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
290 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
291 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
292 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
293 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
294 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
295 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
296 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
297 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
298 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
299 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
300 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
301 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
302 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
303 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
304 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
305 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
306 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
307 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
308 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
309 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
310 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
311 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
312 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
313 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
314 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
315 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
316 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
317 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
318 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
319 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
320 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
321 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
322 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
323 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
324 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
325 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
326 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
327 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
328 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
329 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
330 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
331 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
332 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
333 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
334 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
335 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
336 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
337 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
338 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
339 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
340 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
341 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
342 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
343 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
347 /* Return truth value of whether OP can be used as an operands
348 where a register or 16 bit unsigned integer is needed. */
351 uns_arith_operand (op
, mode
)
353 enum machine_mode mode
;
355 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT_UNSIGNED (op
))
358 return register_operand (op
, mode
);
361 /* Return truth value of whether OP can be used as an operands
362 where a 16 bit integer is needed */
365 arith_operand (op
, mode
)
367 enum machine_mode mode
;
369 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
))
372 return register_operand (op
, mode
);
375 /* Return truth value of whether OP can be used as an operand in a two
376 address arithmetic insn (such as set 123456,%o4) of mode MODE. */
379 arith32_operand (op
, mode
)
381 enum machine_mode mode
;
383 if (GET_CODE (op
) == CONST_INT
)
386 return register_operand (op
, mode
);
389 /* Return truth value of whether OP is a integer which fits in 16 bits */
394 enum machine_mode mode
;
396 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
399 /* Return truth value of whether OP is an integer which is too big to
400 be loaded with one instruction. */
405 enum machine_mode mode
;
409 if (GET_CODE (op
) != CONST_INT
)
413 if ((value
& ~0x0000ffff) == 0) /* ior reg,$r0,value */
416 if (((unsigned long)(value
+ 32768)) <= 32767) /* subu reg,$r0,value */
419 if ((value
& 0xffff0000) == value
) /* lui reg,value>>16 */
425 /* Return truth value of whether OP is a register or the constant 0. */
428 reg_or_0_operand (op
, mode
)
430 enum machine_mode mode
;
432 switch (GET_CODE (op
))
438 return (INTVAL (op
) == 0);
441 if (CONST_DOUBLE_HIGH (op
) != 0 || CONST_DOUBLE_LOW (op
) != 0)
448 return register_operand (op
, mode
);
454 /* Return truth value of whether OP is one of the special multiply/divide
455 registers (hi, lo). */
458 md_register_operand (op
, mode
)
460 enum machine_mode mode
;
462 return (GET_MODE_CLASS (mode
) == MODE_INT
463 && GET_CODE (op
) == REG
464 && MD_REG_P (REGNO (op
)));
467 /* Return truth value of whether OP is the FP status register. */
470 fpsw_register_operand (op
, mode
)
472 enum machine_mode mode
;
474 return (GET_CODE (op
) == REG
&& ST_REG_P (REGNO (op
)));
477 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
480 mips_const_double_ok (op
, mode
)
482 enum machine_mode mode
;
484 if (GET_CODE (op
) != CONST_DOUBLE
)
490 if (mode
!= SFmode
&& mode
!= DFmode
)
493 if (CONST_DOUBLE_HIGH (op
) == 0 && CONST_DOUBLE_LOW (op
) == 0)
496 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
497 if (TARGET_MIPS_AS
) /* gas doesn't like li.d/li.s yet */
499 union { double d
; int i
[2]; } u
;
502 u
.i
[0] = CONST_DOUBLE_LOW (op
);
503 u
.i
[1] = CONST_DOUBLE_HIGH (op
);
507 return FALSE
; /* NAN */
512 /* Rather than trying to get the accuracy down to the last bit,
513 just use approximate ranges. */
515 if (mode
== DFmode
&& d
> 1.0e-300 && d
< 1.0e300
)
518 if (mode
== SFmode
&& d
> 1.0e-38 && d
< 1.0e+38)
526 /* Return truth value if a memory operand fits in a single instruction
527 (ie, register + small offset). */
530 simple_memory_operand (op
, mode
)
532 enum machine_mode mode
;
534 rtx addr
, plus0
, plus1
;
536 /* Eliminate non-memory operations */
537 if (GET_CODE (op
) != MEM
)
540 /* dword operations really put out 2 instructions, so eliminate them. */
541 if (GET_MODE_SIZE (GET_MODE (op
)) > (HAVE_64BIT_P () ? 8 : 4))
544 /* Decode the address now. */
546 switch (GET_CODE (addr
))
555 return SMALL_INT (op
);
558 plus0
= XEXP (addr
, 0);
559 plus1
= XEXP (addr
, 1);
560 if (GET_CODE (plus0
) == REG
561 && GET_CODE (plus1
) == CONST_INT
562 && SMALL_INT (plus1
))
565 else if (GET_CODE (plus1
) == REG
566 && GET_CODE (plus0
) == CONST_INT
567 && SMALL_INT (plus0
))
574 /* We used to allow small symbol refs here (ie, stuff in .sdata
575 or .sbss), but this causes some bugs in G++. Also, it won't
576 interfere if the MIPS linker rewrites the store instruction
577 because the function is PIC. */
579 case LABEL_REF
: /* never gp relative */
583 /* If -G 0, we can never have a GP relative memory operation.
584 Also, save some time if not optimizing. */
585 if (mips_section_threshold
== 0 || !optimize
|| !TARGET_GP_OPT
)
589 rtx offset
= const0_rtx
;
590 addr
= eliminate_constant_term (addr
, &offset
);
591 if (GET_CODE (op
) != SYMBOL_REF
)
594 /* let's be paranoid.... */
595 if (INTVAL (offset
) < 0 || INTVAL (offset
) > 0xffff)
601 return SYMBOL_REF_FLAG (addr
);
608 /* Return true if the code of this rtx pattern is EQ or NE. */
611 equality_op (op
, mode
)
613 enum machine_mode mode
;
615 if (mode
!= GET_MODE (op
))
618 return (classify_op (op
, mode
) & CLASS_EQUALITY_OP
) != 0;
621 /* Return true if the code is a relational operations (EQ, LE, etc.) */
626 enum machine_mode mode
;
628 if (mode
!= GET_MODE (op
))
631 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
635 /* Genrecog does not take the type of match_operator into consideration,
636 and would complain about two patterns being the same if the same
637 function is used, so make it believe they are different. */
642 enum machine_mode mode
;
644 if (mode
!= GET_MODE (op
))
647 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
650 /* Return true if the code is an unsigned relational operations (LEU, etc.) */
655 enum machine_mode mode
;
657 if (mode
!= GET_MODE (op
))
660 return (classify_op (op
, mode
) & CLASS_UNS_CMP_OP
) == CLASS_UNS_CMP_OP
;
663 /* Return true if the code is a relational operation FP can use. */
668 enum machine_mode mode
;
670 if (mode
!= GET_MODE (op
))
673 return (classify_op (op
, mode
) & CLASS_FCMP_OP
) != 0;
677 /* Return true if the operand is either the PC or a label_ref. */
680 pc_or_label_operand (op
, mode
)
682 enum machine_mode mode
;
687 if (GET_CODE (op
) == LABEL_REF
)
694 /* Return an operand string if the given instruction's delay slot or
695 wrap it in a .set noreorder section. This is for filling delay
696 slots on load type instructions under GAS, which does no reordering
697 on its own. For the MIPS assembler, all we do is update the filled
698 delay slot statistics.
700 We assume that operands[0] is the target register that is set.
702 In order to check the next insn, most of this functionality is moved
703 to FINAL_PRESCAN_INSN, and we just set the global variables that
707 mips_fill_delay_slot (ret
, type
, operands
, cur_insn
)
708 char *ret
; /* normal string to return */
709 enum delay_type type
; /* type of delay */
710 rtx operands
[]; /* operands to use */
711 rtx cur_insn
; /* current insn */
713 register rtx set_reg
;
714 register enum machine_mode mode
;
715 register rtx next_insn
= (cur_insn
) ? NEXT_INSN (cur_insn
) : (rtx
)0;
716 register int num_nops
;
718 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
721 else if (type
== DELAY_HILO
)
727 /* Make sure that we don't put nop's after labels. */
728 next_insn
= NEXT_INSN (cur_insn
);
729 while (next_insn
!= (rtx
)0 && GET_CODE (next_insn
) == NOTE
)
730 next_insn
= NEXT_INSN (next_insn
);
732 dslots_load_total
+= num_nops
;
733 if (TARGET_DEBUG_F_MODE
735 || type
== DELAY_NONE
736 || operands
== (rtx
*)0
737 || cur_insn
== (rtx
)0
738 || next_insn
== (rtx
)0
739 || GET_CODE (next_insn
) == CODE_LABEL
740 || (set_reg
= operands
[0]) == (rtx
)0)
742 dslots_number_nops
= 0;
743 mips_load_reg
= (rtx
)0;
744 mips_load_reg2
= (rtx
)0;
745 mips_load_reg3
= (rtx
)0;
746 mips_load_reg4
= (rtx
)0;
750 set_reg
= operands
[0];
751 if (set_reg
== (rtx
)0)
754 while (GET_CODE (set_reg
) == SUBREG
)
755 set_reg
= SUBREG_REG (set_reg
);
757 mode
= GET_MODE (set_reg
);
758 dslots_number_nops
= num_nops
;
759 mips_load_reg
= set_reg
;
760 mips_load_reg2
= (mode
== DImode
|| mode
== DFmode
)
761 ? gen_rtx (REG
, SImode
, REGNO (set_reg
) + 1)
764 if (type
== DELAY_HILO
)
766 mips_load_reg3
= gen_rtx (REG
, SImode
, MD_REG_FIRST
);
767 mips_load_reg4
= gen_rtx (REG
, SImode
, MD_REG_FIRST
+1);
775 if (TARGET_GAS
&& set_noreorder
++ == 0)
776 fputs ("\t.set\tnoreorder\n", asm_out_file
);
782 /* Determine whether a memory reference takes one (based off of the GP pointer),
783 two (normal), or three (label + reg) instructions, and bump the appropriate
784 counter for -mstats. */
787 mips_count_memory_refs (op
, num
)
793 rtx addr
, plus0
, plus1
;
794 enum rtx_code code0
, code1
;
797 if (TARGET_DEBUG_B_MODE
)
799 fprintf (stderr
, "\n========== mips_count_memory_refs:\n");
803 /* Skip MEM if passed, otherwise handle movsi of address. */
804 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
806 /* Loop, going through the address RTL */
810 switch (GET_CODE (addr
))
820 plus0
= XEXP (addr
, 0);
821 plus1
= XEXP (addr
, 1);
822 code0
= GET_CODE (plus0
);
823 code1
= GET_CODE (plus1
);
833 if (code0
== CONST_INT
)
848 if (code1
== CONST_INT
)
855 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
862 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
872 n_words
= 2; /* always 2 words */
876 addr
= XEXP (addr
, 0);
881 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
890 n_words
+= additional
;
894 num_refs
[n_words
-1] += num
;
898 /* Return the appropriate instructions to move one operand to another. */
901 mips_move_1word (operands
, insn
, unsignedp
)
907 rtx op0
= operands
[0];
908 rtx op1
= operands
[1];
909 enum rtx_code code0
= GET_CODE (op0
);
910 enum rtx_code code1
= GET_CODE (op1
);
911 enum machine_mode mode
= GET_MODE (op0
);
912 int subreg_word0
= 0;
913 int subreg_word1
= 0;
914 enum delay_type delay
= DELAY_NONE
;
916 while (code0
== SUBREG
)
918 subreg_word0
+= SUBREG_WORD (op0
);
919 op0
= SUBREG_REG (op0
);
920 code0
= GET_CODE (op0
);
923 while (code1
== SUBREG
)
925 subreg_word1
+= SUBREG_WORD (op1
);
926 op1
= SUBREG_REG (op1
);
927 code1
= GET_CODE (op1
);
932 int regno0
= REGNO (op0
) + subreg_word0
;
936 int regno1
= REGNO (op1
) + subreg_word1
;
938 /* Just in case, don't do anything for assigning a register
939 to itself, unless we are filling a delay slot. */
940 if (regno0
== regno1
&& set_nomacro
== 0)
943 else if (GP_REG_P (regno0
))
945 if (GP_REG_P (regno1
))
948 else if (MD_REG_P (regno1
))
957 if (FP_REG_P (regno1
))
960 else if (regno1
== FPSW_REGNUM
)
961 ret
= "cfc1\t%0,$31";
965 else if (FP_REG_P (regno0
))
967 if (GP_REG_P (regno1
))
973 if (FP_REG_P (regno1
))
974 ret
= "mov.s\t%0,%1";
977 else if (MD_REG_P (regno0
))
979 if (GP_REG_P (regno1
))
986 else if (regno0
== FPSW_REGNUM
)
988 if (GP_REG_P (regno1
))
991 ret
= "ctc1\t%0,$31";
996 else if (code1
== MEM
)
1001 mips_count_memory_refs (op1
, 1);
1003 if (GP_REG_P (regno0
))
1005 /* For loads, use the mode of the memory item, instead of the
1006 target, so zero/sign extend can use this code as well. */
1007 switch (GET_MODE (op1
))
1010 case SFmode
: ret
= "lw\t%0,%1"; break;
1011 case SImode
: ret
= "lw\t%0,%1"; break;
1012 case HImode
: ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1"; break;
1013 case QImode
: ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1"; break;
1017 else if (FP_REG_P (regno0
) && (mode
== SImode
|| mode
== SFmode
))
1020 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1022 int i
= strlen (ret
);
1023 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1026 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1027 ret
= volatile_buffer
;
1031 else if (code1
== CONST_INT
)
1033 if (INTVAL (op1
) == 0)
1035 if (GP_REG_P (regno0
))
1036 ret
= "move\t%0,%z1";
1038 else if (FP_REG_P (regno0
))
1041 ret
= "mtc1\t%z1,%0";
1045 else if (GP_REG_P (regno0
))
1046 ret
= (INTVAL (op1
) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1";
1049 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
1051 if (CONST_DOUBLE_HIGH (op1
) == 0 && CONST_DOUBLE_LOW (op1
) == 0)
1053 if (GP_REG_P (regno0
))
1054 ret
= "move\t%0,%.";
1056 else if (FP_REG_P (regno0
))
1059 ret
= "mtc1\t%.,%0";
1066 ret
= "li.s\t%0,%1";
1070 else if (code1
== LABEL_REF
)
1073 mips_count_memory_refs (op1
, 1);
1078 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
1080 if (HALF_PIC_P () && CONSTANT_P (op1
) && HALF_PIC_ADDRESS_P (op1
))
1082 rtx offset
= const0_rtx
;
1084 if (GET_CODE (op1
) == CONST
)
1085 op1
= eliminate_constant_term (XEXP (op1
, 0), &offset
);
1087 if (GET_CODE (op1
) == SYMBOL_REF
)
1089 operands
[2] = HALF_PIC_PTR (op1
);
1092 mips_count_memory_refs (operands
[2], 1);
1094 if (INTVAL (offset
) == 0)
1101 dslots_load_total
++;
1102 operands
[3] = offset
;
1103 ret
= (SMALL_INT (offset
))
1104 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"
1105 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1112 mips_count_memory_refs (op1
, 1);
1118 else if (code1
== PLUS
)
1120 rtx add_op0
= XEXP (op1
, 0);
1121 rtx add_op1
= XEXP (op1
, 1);
1123 if (GET_CODE (XEXP (op1
, 1)) == REG
&& GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
1125 add_op0
= XEXP (op1
, 1); /* reverse operands */
1126 add_op1
= XEXP (op1
, 0);
1129 operands
[2] = add_op0
;
1130 operands
[3] = add_op1
;
1131 ret
= "add%:\t%0,%2,%3";
1135 else if (code0
== MEM
)
1138 mips_count_memory_refs (op0
, 1);
1142 int regno1
= REGNO (op1
) + subreg_word1
;
1144 if (GP_REG_P (regno1
))
1149 case SFmode
: ret
= "sw\t%1,%0"; break;
1150 case SImode
: ret
= "sw\t%1,%0"; break;
1151 case HImode
: ret
= "sh\t%1,%0"; break;
1152 case QImode
: ret
= "sb\t%1,%0"; break;
1156 else if (FP_REG_P (regno1
) && (mode
== SImode
|| mode
== SFmode
))
1160 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1165 case SFmode
: ret
= "sw\t%z1,%0"; break;
1166 case SImode
: ret
= "sw\t%z1,%0"; break;
1167 case HImode
: ret
= "sh\t%z1,%0"; break;
1168 case QImode
: ret
= "sb\t%z1,%0"; break;
1172 else if (code1
== CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op1
) == 0 && CONST_DOUBLE_LOW (op1
) == 0)
1177 case SFmode
: ret
= "sw\t%.,%0"; break;
1178 case SImode
: ret
= "sw\t%.,%0"; break;
1179 case HImode
: ret
= "sh\t%.,%0"; break;
1180 case QImode
: ret
= "sb\t%.,%0"; break;
1184 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1186 int i
= strlen (ret
);
1187 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1190 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1191 ret
= volatile_buffer
;
1195 if (ret
== (char *)0)
1197 abort_with_insn (insn
, "Bad move");
1201 if (delay
!= DELAY_NONE
)
1202 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1208 /* Return the appropriate instructions to move 2 words */
1211 mips_move_2words (operands
, insn
)
1216 rtx op0
= operands
[0];
1217 rtx op1
= operands
[1];
1218 enum rtx_code code0
= GET_CODE (operands
[0]);
1219 enum rtx_code code1
= GET_CODE (operands
[1]);
1220 int subreg_word0
= 0;
1221 int subreg_word1
= 0;
1222 enum delay_type delay
= DELAY_NONE
;
1224 while (code0
== SUBREG
)
1226 subreg_word0
+= SUBREG_WORD (op0
);
1227 op0
= SUBREG_REG (op0
);
1228 code0
= GET_CODE (op0
);
1231 while (code1
== SUBREG
)
1233 subreg_word1
+= SUBREG_WORD (op1
);
1234 op1
= SUBREG_REG (op1
);
1235 code1
= GET_CODE (op1
);
1240 int regno0
= REGNO (op0
) + subreg_word0
;
1244 int regno1
= REGNO (op1
) + subreg_word1
;
1246 /* Just in case, don't do anything for assigning a register
1247 to itself, unless we are filling a delay slot. */
1248 if (regno0
== regno1
&& set_nomacro
== 0)
1251 else if (FP_REG_P (regno0
))
1253 if (FP_REG_P (regno1
))
1254 ret
= "mov.d\t%0,%1";
1259 ret
= (TARGET_FLOAT64
)
1261 : "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";
1265 else if (FP_REG_P (regno1
))
1268 ret
= (TARGET_FLOAT64
)
1270 : "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";
1273 else if (MD_REG_P (regno0
) && GP_REG_P (regno1
))
1276 ret
= "mthi\t%M1\n\tmtlo\t%L1";
1279 else if (GP_REG_P (regno0
) && MD_REG_P (regno1
))
1282 ret
= "mfhi\t%M0\n\tmflo\t%L0";
1285 else if (regno0
!= (regno1
+1))
1286 ret
= "move\t%0,%1\n\tmove\t%D0,%D1";
1289 ret
= "move\t%D0,%D1\n\tmove\t%0,%1";
1292 else if (code1
== CONST_DOUBLE
)
1294 if (CONST_DOUBLE_HIGH (op1
) != 0 || CONST_DOUBLE_LOW (op1
) != 0)
1296 if (GET_MODE (op1
) == DFmode
)
1299 ret
= "li.d\t%0,%1";
1304 operands
[2] = GEN_INT (CONST_DOUBLE_LOW (op1
));
1305 operands
[3] = GEN_INT (CONST_DOUBLE_HIGH (op1
));
1306 ret
= "li\t%M0,%3\n\tli\t%L0,%2";
1312 if (GP_REG_P (regno0
))
1313 ret
= "move\t%0,%.\n\tmove\t%D0,%.";
1315 else if (FP_REG_P (regno0
))
1318 ret
= (TARGET_FLOAT64
)
1320 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1325 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1327 if (GP_REG_P (regno0
))
1328 ret
= "move\t%0,%.\n\tmove\t%D0,%.";
1330 else if (FP_REG_P (regno0
))
1333 ret
= (TARGET_FLOAT64
)
1335 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1339 else if (code1
== CONST_INT
&& GET_MODE (op0
) == DImode
&& GP_REG_P (regno0
))
1341 operands
[2] = GEN_INT (INTVAL (operands
[1]) >= 0 ? 0 : -1);
1342 ret
= "li\t%M0,%2\n\tli\t%L0,%1";
1345 else if (code1
== MEM
)
1350 mips_count_memory_refs (op1
, 2);
1352 if (FP_REG_P (regno0
))
1355 else if (offsettable_address_p (1, DFmode
, XEXP (op1
, 0)))
1357 operands
[2] = adj_offsettable_operand (op1
, 4);
1358 if (reg_mentioned_p (op0
, op1
))
1359 ret
= "lw\t%D0,%2\n\tlw\t%0,%1";
1361 ret
= "lw\t%0,%1\n\tlw\t%D0,%2";
1364 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1366 int i
= strlen (ret
);
1367 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1370 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1371 ret
= volatile_buffer
;
1376 else if (code0
== MEM
)
1380 int regno1
= REGNO (op1
) + subreg_word1
;
1382 if (FP_REG_P (regno1
))
1385 else if (offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1387 operands
[2] = adj_offsettable_operand (op0
, 4);
1388 ret
= "sw\t%1,%0\n\tsw\t%D1,%2";
1392 else if (code1
== CONST_DOUBLE
1393 && CONST_DOUBLE_HIGH (op1
) == 0
1394 && CONST_DOUBLE_LOW (op1
) == 0
1395 && offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1401 operands
[2] = adj_offsettable_operand (op0
, 4);
1402 ret
= "sw\t%.,%0\n\tsw\t%.,%2";
1407 mips_count_memory_refs (op0
, 2);
1409 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1411 int i
= strlen (ret
);
1412 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1415 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1416 ret
= volatile_buffer
;
1420 if (ret
== (char *)0)
1422 abort_with_insn (insn
, "Bad move");
1426 if (delay
!= DELAY_NONE
)
1427 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1433 /* Provide the costs of an addressing mode that contains ADDR.
1434 If ADDR is not a valid address, its cost is irrelevant. */
1437 mips_address_cost (addr
)
1440 switch (GET_CODE (addr
))
1454 rtx offset
= const0_rtx
;
1455 addr
= eliminate_constant_term (addr
, &offset
);
1456 if (GET_CODE (addr
) == LABEL_REF
)
1459 if (GET_CODE (addr
) != SYMBOL_REF
)
1462 if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
1468 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
1472 register rtx plus0
= XEXP (addr
, 0);
1473 register rtx plus1
= XEXP (addr
, 1);
1475 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1477 plus0
= XEXP (addr
, 1);
1478 plus1
= XEXP (addr
, 0);
1481 if (GET_CODE (plus0
) != REG
)
1484 switch (GET_CODE (plus1
))
1491 int value
= INTVAL (plus1
);
1492 return (value
< -32768 || value
> 32767) ? 2 : 1;
1500 return mips_address_cost (plus1
) + 1;
1509 /* Make normal rtx_code into something we can index from an array */
1511 static enum internal_test
1512 map_test_to_internal_test (test_code
)
1513 enum rtx_code test_code
;
1515 enum internal_test test
= ITEST_MAX
;
1520 case EQ
: test
= ITEST_EQ
; break;
1521 case NE
: test
= ITEST_NE
; break;
1522 case GT
: test
= ITEST_GT
; break;
1523 case GE
: test
= ITEST_GE
; break;
1524 case LT
: test
= ITEST_LT
; break;
1525 case LE
: test
= ITEST_LE
; break;
1526 case GTU
: test
= ITEST_GTU
; break;
1527 case GEU
: test
= ITEST_GEU
; break;
1528 case LTU
: test
= ITEST_LTU
; break;
1529 case LEU
: test
= ITEST_LEU
; break;
1536 /* Generate the code to compare two integer values. The return value is:
1537 (reg:SI xx) The pseudo register the comparison is in
1538 (rtx)0 No register, generate a simple branch. */
1541 gen_int_relational (test_code
, result
, cmp0
, cmp1
, p_invert
)
1542 enum rtx_code test_code
; /* relational test (EQ, etc) */
1543 rtx result
; /* result to store comp. or 0 if branch */
1544 rtx cmp0
; /* first operand to compare */
1545 rtx cmp1
; /* second operand to compare */
1546 int *p_invert
; /* NULL or ptr to hold whether branch needs */
1547 /* to reverse its test */
1550 enum rtx_code test_code
; /* code to use in instruction (LT vs. LTU) */
1551 int const_low
; /* low bound of constant we can accept */
1552 int const_high
; /* high bound of constant we can accept */
1553 int const_add
; /* constant to add (convert LE -> LT) */
1554 int reverse_regs
; /* reverse registers in test */
1555 int invert_const
; /* != 0 if invert value if cmp1 is constant */
1556 int invert_reg
; /* != 0 if invert value if cmp1 is register */
1557 int unsignedp
; /* != 0 for unsigned comparisons. */
1560 static struct cmp_info info
[ (int)ITEST_MAX
] = {
1562 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1563 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1564 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1565 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1566 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1567 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1568 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1569 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1570 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1571 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1574 enum internal_test test
;
1575 struct cmp_info
*p_info
;
1582 test
= map_test_to_internal_test (test_code
);
1583 if (test
== ITEST_MAX
)
1586 p_info
= &info
[ (int)test
];
1587 eqne_p
= (p_info
->test_code
== XOR
);
1589 /* Eliminate simple branches */
1590 branch_p
= (result
== (rtx
)0);
1593 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
1595 /* Comparisons against zero are simple branches */
1596 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1599 /* Test for beq/bne. */
1604 /* allocate a pseudo to calculate the value in. */
1605 result
= gen_reg_rtx (SImode
);
1608 /* Make sure we can handle any constants given to us. */
1609 if (GET_CODE (cmp0
) == CONST_INT
)
1610 cmp0
= force_reg (SImode
, cmp0
);
1612 if (GET_CODE (cmp1
) == CONST_INT
)
1614 HOST_WIDE_INT value
= INTVAL (cmp1
);
1615 if (value
< p_info
->const_low
|| value
> p_info
->const_high
)
1616 cmp1
= force_reg (SImode
, cmp1
);
1619 /* See if we need to invert the result. */
1620 invert
= (GET_CODE (cmp1
) == CONST_INT
)
1621 ? p_info
->invert_const
1622 : p_info
->invert_reg
;
1624 if (p_invert
!= (int *)0)
1630 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1631 Comparison between two registers, may involve switching operands. */
1632 if (GET_CODE (cmp1
) == CONST_INT
)
1634 if (p_info
->const_add
!= 0)
1636 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
1637 /* If modification of cmp1 caused overflow,
1638 we would get the wrong answer if we follow the usual path;
1639 thus, x > 0xffffffffu would turn into x > 0u. */
1640 if ((p_info
->unsignedp
1641 ? (unsigned HOST_WIDE_INT
) new > INTVAL (cmp1
)
1642 : new > INTVAL (cmp1
))
1643 != (p_info
->const_add
> 0))
1644 /* 1 is the right value in the LE and LEU case.
1645 In the GT and GTU case, *p_invert is already set,
1646 so this is effectively 0. */
1647 return force_reg (SImode
, const1_rtx
);
1649 cmp1
= GEN_INT (new);
1652 else if (p_info
->reverse_regs
)
1659 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1663 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (SImode
) : result
;
1664 emit_move_insn (reg
, gen_rtx (p_info
->test_code
, SImode
, cmp0
, cmp1
));
1667 if (test
== ITEST_NE
)
1669 emit_move_insn (result
, gen_rtx (GTU
, SImode
, reg
, const0_rtx
));
1673 else if (test
== ITEST_EQ
)
1675 reg2
= (invert
) ? gen_reg_rtx (SImode
) : result
;
1676 emit_move_insn (reg2
, gen_rtx (LTU
, SImode
, reg
, const1_rtx
));
1681 emit_move_insn (result
, gen_rtx (XOR
, SImode
, reg
, const1_rtx
));
1687 /* Emit the common code for doing conditional branches.
1688 operand[0] is the label to jump to.
1689 The comparison operands are saved away by cmp{si,sf,df}. */
1692 gen_conditional_branch (operands
, test_code
)
1694 enum rtx_code test_code
;
1696 static enum machine_mode mode_map
[(int)CMP_MAX
][(int)ITEST_MAX
] = {
1711 CC_REV_FPmode
, /* ne */
1723 CC_REV_FPmode
, /* ne */
1735 enum machine_mode mode
;
1736 enum cmp_type type
= branch_type
;
1737 rtx cmp0
= branch_cmp
[0];
1738 rtx cmp1
= branch_cmp
[1];
1739 rtx label1
= gen_rtx (LABEL_REF
, VOIDmode
, operands
[0]);
1740 rtx label2
= pc_rtx
;
1743 enum internal_test test
= map_test_to_internal_test (test_code
);
1745 if (test
== ITEST_MAX
)
1751 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
1752 mode
= mode_map
[(int)type
][(int)test
];
1753 if (mode
== VOIDmode
)
1756 switch (branch_type
)
1762 reg
= gen_int_relational (test_code
, (rtx
)0, cmp0
, cmp1
, &invert
);
1770 /* Make sure not non-zero constant if ==/!= */
1771 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1772 cmp1
= force_reg (SImode
, cmp1
);
1779 rtx reg
= gen_rtx (REG
, mode
, FPSW_REGNUM
);
1780 emit_insn (gen_rtx (SET
, VOIDmode
, reg
, gen_rtx (test_code
, mode
, cmp0
, cmp1
)));
1788 /* Generate the jump */
1795 emit_jump_insn (gen_rtx (SET
, VOIDmode
,
1797 gen_rtx (IF_THEN_ELSE
, VOIDmode
,
1798 gen_rtx (test_code
, mode
, cmp0
, cmp1
),
1805 abort_with_insn (gen_rtx (test_code
, mode
, cmp0
, cmp1
), "bad test");
1809 #define UNITS_PER_SHORT (SHORT_TYPE_SIZE / BITS_PER_UNIT)
1811 /* Internal code to generate the load and store of one word/short/byte.
1812 The load is emitted directly, and the store insn is returned. */
1816 block_move_load_store (dest_reg
, src_reg
, p_bytes
, p_offset
, align
, orig_src
)
1817 rtx src_reg
; /* register holding source memory address */
1818 rtx dest_reg
; /* register holding dest. memory address */
1819 int *p_bytes
; /* pointer to # bytes remaining */
1820 int *p_offset
; /* pointer to current offset */
1821 int align
; /* alignment */
1822 rtx orig_src
; /* original source for making a reg note */
1824 int bytes
; /* # bytes remaining */
1825 int offset
; /* offset to use */
1826 int size
; /* size in bytes of load/store */
1827 enum machine_mode mode
; /* mode to use for load/store */
1828 rtx reg
; /* temporary register */
1829 rtx src_addr
; /* source address */
1830 rtx dest_addr
; /* destination address */
1831 rtx insn
; /* insn of the load */
1832 rtx orig_src_addr
; /* original source address */
1833 rtx (*load_func
)(); /* function to generate load insn */
1834 rtx (*store_func
)(); /* function to generate destination insn */
1837 if (bytes
<= 0 || align
<= 0)
1840 if (bytes
>= UNITS_PER_WORD
&& align
>= UNITS_PER_WORD
)
1843 size
= UNITS_PER_WORD
;
1844 load_func
= gen_movsi
;
1845 store_func
= gen_movsi
;
1849 /* Don't generate unligned moves here, rather defer those to the
1850 general movestrsi_internal pattern. */
1851 else if (bytes
>= UNITS_PER_WORD
)
1854 size
= UNITS_PER_WORD
;
1855 load_func
= gen_movsi_ulw
;
1856 store_func
= gen_movsi_usw
;
1860 else if (bytes
>= UNITS_PER_SHORT
&& align
>= UNITS_PER_SHORT
)
1863 size
= UNITS_PER_SHORT
;
1864 load_func
= gen_movhi
;
1865 store_func
= gen_movhi
;
1872 load_func
= gen_movqi
;
1873 store_func
= gen_movqi
;
1877 *p_offset
= offset
+ size
;
1878 *p_bytes
= bytes
- size
;
1883 dest_addr
= dest_reg
;
1887 src_addr
= gen_rtx (PLUS
, Pmode
, src_reg
, GEN_INT (offset
));
1888 dest_addr
= gen_rtx (PLUS
, Pmode
, dest_reg
, GEN_INT (offset
));
1891 reg
= gen_reg_rtx (mode
);
1892 insn
= emit_insn ((*load_func
) (reg
, gen_rtx (MEM
, mode
, src_addr
)));
1893 orig_src_addr
= XEXP (orig_src
, 0);
1894 if (CONSTANT_P (orig_src_addr
))
1895 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUIV
,
1896 plus_constant (orig_src_addr
, offset
),
1899 return (*store_func
) (gen_rtx (MEM
, mode
, dest_addr
), reg
);
1904 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows:
1916 This way, no NOP's are needed, except at the end, and only
1917 two temp registers are needed. Two delay slots are used
1918 in deference to the R4000. */
1922 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
)
1923 rtx dest_reg
; /* register holding destination address */
1924 rtx src_reg
; /* register holding source address */
1925 int bytes
; /* # bytes to move */
1926 int align
; /* max alignment to assume */
1927 rtx orig_src
; /* original source for making a reg note */
1930 rtx prev2_store
= (rtx
)0;
1931 rtx prev_store
= (rtx
)0;
1932 rtx cur_store
= (rtx
)0;
1936 /* Is there a store to do? */
1938 emit_insn (prev2_store
);
1940 prev2_store
= prev_store
;
1941 prev_store
= cur_store
;
1942 cur_store
= block_move_load_store (dest_reg
, src_reg
,
1947 /* Finish up last three stores. */
1949 emit_insn (prev2_store
);
1952 emit_insn (prev_store
);
1955 emit_insn (cur_store
);
1960 /* Write a loop to move a constant number of bytes. Generate load/stores as follows:
1966 temp<last> = src[MAX_MOVE_REGS-1];
1970 dest[MAX_MOVE_REGS-1] = temp<last>;
1971 src += MAX_MOVE_REGS;
1972 dest += MAX_MOVE_REGS;
1973 } while (src != final);
1975 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp
1976 registers are needed.
1978 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3
1979 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every
1980 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */
1982 #define MAX_MOVE_REGS 4
1983 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
1986 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
)
1987 rtx dest_reg
; /* register holding destination address */
1988 rtx src_reg
; /* register holding source address */
1989 int bytes
; /* # bytes to move */
1990 int align
; /* alignment */
1991 rtx orig_src
; /* original source for making a reg note */
1993 rtx dest_mem
= gen_rtx (MEM
, BLKmode
, dest_reg
);
1994 rtx src_mem
= gen_rtx (MEM
, BLKmode
, src_reg
);
1995 rtx align_rtx
= GEN_INT (align
);
2001 if (bytes
< 2*MAX_MOVE_BYTES
)
2004 leftover
= bytes
% MAX_MOVE_BYTES
;
2007 label
= gen_label_rtx ();
2008 final_src
= gen_reg_rtx (Pmode
);
2009 bytes_rtx
= GEN_INT (bytes
);
2013 emit_insn (gen_movsi (final_src
, bytes_rtx
));
2014 emit_insn (gen_addsi3 (final_src
, final_src
, src_reg
));
2017 emit_insn (gen_addsi3 (final_src
, src_reg
, bytes_rtx
));
2021 bytes_rtx
= GEN_INT (MAX_MOVE_BYTES
);
2022 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
, bytes_rtx
, align_rtx
));
2023 emit_insn (gen_addsi3 (src_reg
, src_reg
, bytes_rtx
));
2024 emit_insn (gen_addsi3 (dest_reg
, dest_reg
, bytes_rtx
));
2025 emit_insn (gen_cmpsi (src_reg
, final_src
));
2026 emit_jump_insn (gen_bne (label
));
2029 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
,
2035 /* Use a library function to move some bytes. */
2038 block_move_call (dest_reg
, src_reg
, bytes_rtx
)
2043 #ifdef TARGET_MEM_FUNCTIONS
2044 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "memcpy"), 0,
2050 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "bcopy"), 0,
2059 /* Expand string/block move operations.
2061 operands[0] is the pointer to the destination.
2062 operands[1] is the pointer to the source.
2063 operands[2] is the number of bytes to move.
2064 operands[3] is the alignment. */
2067 expand_block_move (operands
)
2070 rtx bytes_rtx
= operands
[2];
2071 rtx align_rtx
= operands
[3];
2072 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2073 int bytes
= (constp
? INTVAL (bytes_rtx
) : 0);
2074 int align
= INTVAL (align_rtx
);
2075 rtx orig_src
= operands
[1];
2079 if (constp
&& bytes
<= 0)
2082 if (align
> UNITS_PER_WORD
)
2083 align
= UNITS_PER_WORD
;
2085 /* Move the address into scratch registers. */
2086 dest_reg
= copy_addr_to_reg (XEXP (operands
[0], 0));
2087 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2090 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2093 else if (constp
&& bytes
<= 3*align
)
2094 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2097 else if (constp
&& bytes
<= 2*MAX_MOVE_BYTES
)
2098 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2099 gen_rtx (MEM
, BLKmode
, src_reg
),
2100 bytes_rtx
, align_rtx
));
2102 else if (constp
&& align
>= UNITS_PER_WORD
&& optimize
)
2103 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2105 else if (constp
&& optimize
)
2107 /* If the alignment is not word aligned, generate a test at
2108 runtime, to see whether things wound up aligned, and we
2109 can use the faster lw/sw instead ulw/usw. */
2111 rtx temp
= gen_reg_rtx (Pmode
);
2112 rtx aligned_label
= gen_label_rtx ();
2113 rtx join_label
= gen_label_rtx ();
2114 int leftover
= bytes
% MAX_MOVE_BYTES
;
2118 emit_insn (gen_iorsi3 (temp
, src_reg
, dest_reg
));
2119 emit_insn (gen_andsi3 (temp
, temp
, GEN_INT (UNITS_PER_WORD
-1)));
2120 emit_insn (gen_cmpsi (temp
, const0_rtx
));
2121 emit_jump_insn (gen_beq (aligned_label
));
2123 /* Unaligned loop. */
2124 block_move_loop (dest_reg
, src_reg
, bytes
, 1, orig_src
);
2125 emit_jump_insn (gen_jump (join_label
));
2129 emit_label (aligned_label
);
2130 block_move_loop (dest_reg
, src_reg
, bytes
, UNITS_PER_WORD
, orig_src
);
2131 emit_label (join_label
);
2133 /* Bytes at the end of the loop. */
2137 if (leftover
<= 3*align
)
2138 block_move_sequence (dest_reg
, src_reg
, leftover
, align
, orig_src
);
2142 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2143 gen_rtx (MEM
, BLKmode
, src_reg
),
2150 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2154 /* Emit load/stores for a small constant block_move.
2156 operands[0] is the memory address of the destination.
2157 operands[1] is the memory address of the source.
2158 operands[2] is the number of bytes to move.
2159 operands[3] is the alignment.
2160 operands[4] is a temp register.
2161 operands[5] is a temp register.
2163 operands[3+num_regs] is the last temp register.
2165 The block move type can be one of the following:
2166 BLOCK_MOVE_NORMAL Do all of the block move.
2167 BLOCK_MOVE_NOT_LAST Do all but the last store.
2168 BLOCK_MOVE_LAST Do just the last store. */
2171 output_block_move (insn
, operands
, num_regs
, move_type
)
2175 enum block_move_type move_type
;
2177 rtx dest_reg
= XEXP (operands
[0], 0);
2178 rtx src_reg
= XEXP (operands
[1], 0);
2179 int bytes
= INTVAL (operands
[2]);
2180 int align
= INTVAL (operands
[3]);
2183 int use_lwl_lwr
= FALSE
;
2184 int last_operand
= num_regs
+4;
2189 char *load
; /* load insn without nop */
2190 char *load_nop
; /* load insn with trailing nop */
2191 char *store
; /* store insn */
2192 char *final
; /* if last_store used: NULL or swr */
2193 char *last_store
; /* last store instruction */
2194 int offset
; /* current offset */
2195 enum machine_mode mode
; /* mode to use on (MEM) */
2198 /* Detect a bug in GCC, where it can give us a register
2199 the same as one of the addressing registers. */
2200 for (i
= 4; i
< last_operand
; i
++)
2202 if (reg_mentioned_p (operands
[i
], operands
[0])
2203 || reg_mentioned_p (operands
[i
], operands
[1]))
2205 abort_with_insn (insn
, "register passed as address and temp register to block move");
2209 /* If we are given global or static addresses, and we would be
2210 emitting a few instructions, try to save time by using a
2211 temporary register for the pointer. */
2212 if (bytes
> 2*align
|| move_type
!= BLOCK_MOVE_NORMAL
)
2214 if (CONSTANT_P (src_reg
))
2217 mips_count_memory_refs (operands
[1], 1);
2219 src_reg
= operands
[ 3 + num_regs
-- ];
2220 if (move_type
!= BLOCK_MOVE_LAST
)
2222 xoperands
[1] = operands
[1];
2223 xoperands
[0] = src_reg
;
2224 output_asm_insn ("la\t%0,%1", xoperands
);
2228 if (CONSTANT_P (dest_reg
))
2231 mips_count_memory_refs (operands
[0], 1);
2233 dest_reg
= operands
[ 3 + num_regs
-- ];
2234 if (move_type
!= BLOCK_MOVE_LAST
)
2236 xoperands
[1] = operands
[0];
2237 xoperands
[0] = dest_reg
;
2238 output_asm_insn ("la\t%0,%1", xoperands
);
2243 if (num_regs
> (sizeof (load_store
) / sizeof (load_store
[0])))
2244 num_regs
= (sizeof (load_store
) / sizeof (load_store
[0]));
2246 else if (num_regs
< 1)
2249 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& set_noreorder
++ == 0)
2250 output_asm_insn (".set\tnoreorder", operands
);
2254 load_store
[num
].offset
= offset
;
2256 if (bytes
>= UNITS_PER_WORD
&& align
>= UNITS_PER_WORD
)
2258 load_store
[num
].load
= "lw\t%0,%1";
2259 load_store
[num
].load_nop
= "lw\t%0,%1%#";
2260 load_store
[num
].store
= "sw\t%0,%1";
2261 load_store
[num
].last_store
= "sw\t%0,%1";
2262 load_store
[num
].final
= (char *)0;
2263 load_store
[num
].mode
= SImode
;
2264 offset
+= UNITS_PER_WORD
;
2265 bytes
-= UNITS_PER_WORD
;
2268 else if (bytes
>= UNITS_PER_WORD
)
2270 #if BYTES_BIG_ENDIAN
2271 load_store
[num
].load
= "lwl\t%0,%1\n\tlwr\t%0,%2";
2272 load_store
[num
].load_nop
= "lwl\t%0,%1\n\tlwr\t%0,%2%#";
2273 load_store
[num
].store
= "swl\t%0,%1\n\tswr\t%0,%2";
2274 load_store
[num
].last_store
= "swr\t%0,%2";
2275 load_store
[num
].final
= "swl\t%0,%1";
2277 load_store
[num
].load
= "lwl\t%0,%2\n\tlwr\t%0,%1";
2278 load_store
[num
].load_nop
= "lwl\t%0,%2\n\tlwr\t%0,%1%#";
2279 load_store
[num
].store
= "swl\t%0,%2\n\tswr\t%0,%1";
2280 load_store
[num
].last_store
= "swr\t%0,%1";
2281 load_store
[num
].final
= "swl\t%0,%2";
2283 load_store
[num
].mode
= SImode
;
2284 offset
+= UNITS_PER_WORD
;
2285 bytes
-= UNITS_PER_WORD
;
2289 else if (bytes
>= UNITS_PER_SHORT
&& align
>= UNITS_PER_SHORT
)
2291 load_store
[num
].load
= "lh\t%0,%1";
2292 load_store
[num
].load_nop
= "lh\t%0,%1%#";
2293 load_store
[num
].store
= "sh\t%0,%1";
2294 load_store
[num
].last_store
= "sh\t%0,%1";
2295 load_store
[num
].final
= (char *)0;
2296 load_store
[num
].offset
= offset
;
2297 load_store
[num
].mode
= HImode
;
2298 offset
+= UNITS_PER_SHORT
;
2299 bytes
-= UNITS_PER_SHORT
;
2304 load_store
[num
].load
= "lb\t%0,%1";
2305 load_store
[num
].load_nop
= "lb\t%0,%1%#";
2306 load_store
[num
].store
= "sb\t%0,%1";
2307 load_store
[num
].last_store
= "sb\t%0,%1";
2308 load_store
[num
].final
= (char *)0;
2309 load_store
[num
].mode
= QImode
;
2314 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2316 dslots_load_total
++;
2317 dslots_load_filled
++;
2319 if (CONSTANT_P (src_reg
))
2320 mips_count_memory_refs (src_reg
, 1);
2322 if (CONSTANT_P (dest_reg
))
2323 mips_count_memory_refs (dest_reg
, 1);
2326 /* Emit load/stores now if we have run out of registers or are
2327 at the end of the move. */
2329 if (++num
== num_regs
|| bytes
== 0)
2331 /* If only load/store, we need a NOP after the load. */
2334 load_store
[0].load
= load_store
[0].load_nop
;
2335 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2336 dslots_load_filled
--;
2339 if (move_type
!= BLOCK_MOVE_LAST
)
2341 for (i
= 0; i
< num
; i
++)
2348 if (GET_MODE (operands
[i
+4]) != load_store
[i
].mode
)
2349 operands
[i
+4] = gen_rtx (REG
, load_store
[i
].mode
, REGNO (operands
[i
+4]));
2351 offset
= load_store
[i
].offset
;
2352 xoperands
[0] = operands
[i
+4];
2353 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2354 plus_constant (src_reg
, offset
));
2357 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2358 plus_constant (src_reg
, UNITS_PER_WORD
-1+offset
));
2360 output_asm_insn (load_store
[i
].load
, xoperands
);
2364 for (i
= 0; i
< num
; i
++)
2366 int last_p
= (i
== num
-1 && bytes
== 0);
2367 int offset
= load_store
[i
].offset
;
2369 xoperands
[0] = operands
[i
+4];
2370 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2371 plus_constant (dest_reg
, offset
));
2375 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2376 plus_constant (dest_reg
, UNITS_PER_WORD
-1+offset
));
2378 if (move_type
== BLOCK_MOVE_NORMAL
)
2379 output_asm_insn (load_store
[i
].store
, xoperands
);
2381 else if (move_type
== BLOCK_MOVE_NOT_LAST
)
2384 output_asm_insn (load_store
[i
].store
, xoperands
);
2386 else if (load_store
[i
].final
!= (char *)0)
2387 output_asm_insn (load_store
[i
].final
, xoperands
);
2391 output_asm_insn (load_store
[i
].last_store
, xoperands
);
2394 num
= 0; /* reset load_store */
2395 use_lwl_lwr
= FALSE
; /* reset whether or not we used lwl/lwr */
2399 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& --set_noreorder
== 0)
2400 output_asm_insn (".set\treorder", operands
);
2406 /* Argument support functions. */
2408 /* Initialize CUMULATIVE_ARGS for a function. */
2411 init_cumulative_args (cum
, fntype
, libname
)
2412 CUMULATIVE_ARGS
*cum
; /* argument info to initialize */
2413 tree fntype
; /* tree ptr for function decl */
2414 rtx libname
; /* SYMBOL_REF of library name or 0 */
2416 tree param
, next_param
;
2418 if (TARGET_DEBUG_E_MODE
)
2420 fprintf (stderr
, "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype
);
2422 fputc ('\n', stderr
);
2426 tree ret_type
= TREE_TYPE (fntype
);
2427 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
2428 tree_code_name
[ (int)TREE_CODE (fntype
) ],
2429 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
2433 cum
->gp_reg_found
= 0;
2434 cum
->arg_number
= 0;
2437 /* Determine if this function has variable arguments. This is
2438 indicated by the last argument being 'void_type_mode' if there
2439 are no variable arguments. The standard MIPS calling sequence
2440 passes all arguments in the general purpose registers in this
2443 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
2447 next_param
= TREE_CHAIN (param
);
2448 if (next_param
== (tree
)0 && TREE_VALUE (param
) != void_type_node
)
2449 cum
->gp_reg_found
= 1;
2453 /* Advance the argument to the next argument position. */
2456 function_arg_advance (cum
, mode
, type
, named
)
2457 CUMULATIVE_ARGS
*cum
; /* current arg information */
2458 enum machine_mode mode
; /* current arg mode */
2459 tree type
; /* type of the argument or 0 if lib support */
2460 int named
; /* whether or not the argument was named */
2462 if (TARGET_DEBUG_E_MODE
)
2464 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n",
2465 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2472 error ("Illegal mode given to function_arg_advance");
2479 cum
->gp_reg_found
= 1;
2480 cum
->arg_words
+= (int_size_in_bytes (type
) + 3) / 4;
2488 cum
->arg_words
+= 2;
2492 cum
->gp_reg_found
= 1;
2493 cum
->arg_words
+= 2;
2499 cum
->gp_reg_found
= 1;
2505 /* Return a RTL expression containing the register for the given mode,
2506 or 0 if the argument is too be passed on the stack. */
2509 function_arg (cum
, mode
, type
, named
)
2510 CUMULATIVE_ARGS
*cum
; /* current arg information */
2511 enum machine_mode mode
; /* current arg mode */
2512 tree type
; /* type of the argument or 0 if lib support */
2513 int named
; /* != 0 for normal args, == 0 for ... args */
2518 if (TARGET_DEBUG_E_MODE
)
2520 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ",
2521 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2527 error ("Illegal mode given to function_arg");
2531 if (cum
->gp_reg_found
|| cum
->arg_number
>= 2)
2532 regbase
= GP_ARG_FIRST
;
2534 regbase
= (TARGET_SOFT_FLOAT
) ? GP_ARG_FIRST
: FP_ARG_FIRST
;
2535 if (cum
->arg_words
== 1) /* first arg was float */
2536 bias
= 1; /* use correct reg */
2542 cum
->arg_words
+= (cum
->arg_words
& 1);
2543 regbase
= (cum
->gp_reg_found
|| TARGET_SOFT_FLOAT
)
2549 if (type
!= (tree
)0 && TYPE_ALIGN (type
) > BITS_PER_WORD
)
2550 cum
->arg_words
+= (cum
->arg_words
& 1);
2552 regbase
= GP_ARG_FIRST
;
2559 regbase
= GP_ARG_FIRST
;
2563 cum
->arg_words
+= (cum
->arg_words
& 1);
2564 regbase
= GP_ARG_FIRST
;
2567 if (cum
->arg_words
>= MAX_ARGS_IN_REGISTERS
)
2569 if (TARGET_DEBUG_E_MODE
)
2570 fprintf (stderr
, "<stack>\n");
2578 if (TARGET_DEBUG_E_MODE
)
2579 fprintf (stderr
, "%s\n", reg_names
[regbase
+ cum
->arg_words
+ bias
]);
2581 return gen_rtx (REG
, mode
, regbase
+ cum
->arg_words
+ bias
);
2586 function_arg_partial_nregs (cum
, mode
, type
, named
)
2587 CUMULATIVE_ARGS
*cum
; /* current arg information */
2588 enum machine_mode mode
; /* current arg mode */
2589 tree type
; /* type of the argument or 0 if lib support */
2590 int named
; /* != 0 for normal args, == 0 for ... args */
2592 if (mode
== BLKmode
&& cum
->arg_words
< MAX_ARGS_IN_REGISTERS
)
2594 int words
= (int_size_in_bytes (type
) + 3) / 4;
2596 if (words
+ cum
->arg_words
< MAX_ARGS_IN_REGISTERS
)
2597 return 0; /* structure fits in registers */
2599 if (TARGET_DEBUG_E_MODE
)
2600 fprintf (stderr
, "function_arg_partial_nregs = %d\n",
2601 MAX_ARGS_IN_REGISTERS
- cum
->arg_words
);
2603 return MAX_ARGS_IN_REGISTERS
- cum
->arg_words
;
2606 else if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
-1)
2608 if (TARGET_DEBUG_E_MODE
)
2609 fprintf (stderr
, "function_arg_partial_nregs = 1\n");
2618 /* Print the options used in the assembly file. */
2620 static struct {char *name
; int value
;} target_switches
[]
2631 int mask
= TARGET_DEFAULT
;
2633 /* Allow assembly language comparisons with -mdebug eliminating the
2634 compiler version number and switch lists. */
2636 if (TARGET_DEBUG_MODE
)
2639 fprintf (out
, "\n # %s %s", language_string
, version_string
);
2640 #ifdef TARGET_VERSION_INTERNAL
2641 TARGET_VERSION_INTERNAL (out
);
2644 fprintf (out
, " compiled by GNU C\n\n");
2646 fprintf (out
, " compiled by CC\n\n");
2649 fprintf (out
, " # Cc1 defaults:");
2651 for (j
= 0; j
< sizeof target_switches
/ sizeof target_switches
[0]; j
++)
2653 if (target_switches
[j
].name
[0] != '\0'
2654 && target_switches
[j
].value
> 0
2655 && (target_switches
[j
].value
& mask
) == target_switches
[j
].value
)
2657 mask
&= ~ target_switches
[j
].value
;
2658 len
= strlen (target_switches
[j
].name
) + 1;
2659 if (len
+ line_len
> 79)
2662 fputs ("\n #", out
);
2664 fprintf (out
, " -m%s", target_switches
[j
].name
);
2669 fprintf (out
, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):",
2670 mips_section_threshold
, mips_cpu_string
, mips_isa
);
2673 for (p
= &save_argv
[1]; *p
!= (char *)0; p
++)
2678 len
= strlen (arg
) + 1;
2679 if (len
+ line_len
> 79)
2682 fputs ("\n #", out
);
2684 fprintf (out
, " %s", *p
);
2689 fputs ("\n\n", out
);
2693 /* Abort after printing out a specific insn. */
2696 abort_with_insn (insn
, reason
)
2705 /* Write a message to stderr (for use in macros expanded in files that do not
2706 include stdio.h). */
2712 fprintf (stderr
, s
, s1
, s2
);
2722 fprintf (stderr
, "compiling '%s' in '%s'\n",
2723 (current_function_name
!= (char *)0) ? current_function_name
: "<toplevel>",
2724 (current_function_file
!= (char *)0) ? current_function_file
: "<no file>");
2727 #endif /* SIGINFO */
2730 /* Set up the threshold for data to go into the small data area, instead
2731 of the normal data area, and detect any conflicts in the switches. */
2736 register int i
, start
;
2738 register enum machine_mode mode
;
2741 mips_section_threshold
= g_switch_value
;
2744 mips_section_threshold
= (TARGET_MIPS_AS
) ? 8 : 0;
2746 /* Identify the processor type */
2747 if (mips_cpu_string
== (char *)0
2748 || !strcmp (mips_cpu_string
, "default")
2749 || !strcmp (mips_cpu_string
, "DEFAULT"))
2751 mips_cpu_string
= "default";
2752 mips_cpu
= PROCESSOR_DEFAULT
;
2757 char *p
= mips_cpu_string
;
2759 if (*p
== 'r' || *p
== 'R')
2762 /* Since there is no difference between a R2000 and R3000 in
2763 terms of the scheduler, we collapse them into just an R3000. */
2765 mips_cpu
= PROCESSOR_DEFAULT
;
2769 if (!strcmp (p
, "2000") || !strcmp (p
, "2k") || !strcmp (p
, "2K"))
2770 mips_cpu
= PROCESSOR_R3000
;
2774 if (!strcmp (p
, "3000") || !strcmp (p
, "3k") || !strcmp (p
, "3K"))
2775 mips_cpu
= PROCESSOR_R3000
;
2779 if (!strcmp (p
, "4000") || !strcmp (p
, "4k") || !strcmp (p
, "4K"))
2780 mips_cpu
= PROCESSOR_R4000
;
2784 if (!strcmp (p
, "6000") || !strcmp (p
, "6k") || !strcmp (p
, "6K"))
2785 mips_cpu
= PROCESSOR_R6000
;
2789 if (mips_cpu
== PROCESSOR_DEFAULT
)
2791 error ("bad value (%s) for -mcpu= switch", mips_cpu_string
);
2792 mips_cpu_string
= "default";
2796 /* Now get the architectural level. */
2797 if (mips_isa_string
== (char *)0)
2800 else if (isdigit (*mips_isa_string
))
2801 mips_isa
= atoi (mips_isa_string
);
2805 error ("bad value (%s) for -mips switch", mips_isa_string
);
2809 if (mips_isa
< 0 || mips_isa
> 3)
2810 error ("-mips%d not supported", mips_isa
);
2812 else if (mips_isa
> 1
2813 && (mips_cpu
== PROCESSOR_DEFAULT
|| mips_cpu
== PROCESSOR_R3000
))
2814 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
2816 else if (mips_cpu
== PROCESSOR_R6000
&& mips_isa
> 2)
2817 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
2819 /* make sure sizes of ints/longs/etc. are ok */
2823 fatal ("Only the r4000 can support 64 bit ints");
2825 else if (TARGET_LONG64
)
2826 fatal ("Only the r4000 can support 64 bit longs");
2828 else if (TARGET_LLONG128
)
2829 fatal ("Only the r4000 can support 128 bit long longs");
2831 else if (TARGET_FLOAT64
)
2832 fatal ("Only the r4000 can support 64 bit fp registers");
2834 else if (TARGET_INT64
|| TARGET_LONG64
|| TARGET_LLONG128
|| TARGET_FLOAT64
)
2835 warning ("r4000 64/128 bit types not yet supported");
2837 /* Tell halfpic.c that we have half-pic code if we do. */
2838 if (TARGET_HALF_PIC
)
2841 /* -mrnames says to use the MIPS software convention for register
2842 names instead of the hardware names (ie, a0 instead of $4).
2843 We do this by switching the names in mips_reg_names, which the
2844 reg_names points into via the REGISTER_NAMES macro. */
2846 if (TARGET_NAME_REGS
)
2850 target_flags
&= ~ MASK_NAME_REGS
;
2851 error ("Gas does not support the MIPS software register name convention.");
2854 bcopy ((char *) mips_sw_reg_names
, (char *) mips_reg_names
, sizeof (mips_reg_names
));
2857 /* If this is OSF/1, set up a SIGINFO handler so we can see what function
2858 is currently being compiled. */
2860 if (getenv ("GCC_SIGINFO") != (char *)0)
2862 struct sigaction action
;
2863 action
.sa_handler
= siginfo
;
2865 action
.sa_flags
= SA_RESTART
;
2866 sigaction (SIGINFO
, &action
, (struct sigaction
*)0);
2871 #if defined(ultrix) || defined(__ultrix) || defined(__OSF1__) || defined(__osf__) || defined(osf)
2872 /* If -mstats and -quiet, make stderr line buffered. */
2873 if (quiet_flag
&& TARGET_STATS
)
2874 setvbuf (stderr
, (char *)0, _IOLBF
, BUFSIZ
);
2878 /* Set up the classification arrays now. */
2879 mips_rtx_classify
[(int)PLUS
] = CLASS_ADD_OP
;
2880 mips_rtx_classify
[(int)MINUS
] = CLASS_ADD_OP
;
2881 mips_rtx_classify
[(int)DIV
] = CLASS_DIVMOD_OP
;
2882 mips_rtx_classify
[(int)MOD
] = CLASS_DIVMOD_OP
;
2883 mips_rtx_classify
[(int)UDIV
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
2884 mips_rtx_classify
[(int)UMOD
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
2885 mips_rtx_classify
[(int)EQ
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
2886 mips_rtx_classify
[(int)NE
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
2887 mips_rtx_classify
[(int)GT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2888 mips_rtx_classify
[(int)GE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2889 mips_rtx_classify
[(int)LT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2890 mips_rtx_classify
[(int)LE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2891 mips_rtx_classify
[(int)GTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2892 mips_rtx_classify
[(int)GEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2893 mips_rtx_classify
[(int)LTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2894 mips_rtx_classify
[(int)LEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2896 mips_print_operand_punct
['?'] = TRUE
;
2897 mips_print_operand_punct
['#'] = TRUE
;
2898 mips_print_operand_punct
['&'] = TRUE
;
2899 mips_print_operand_punct
['!'] = TRUE
;
2900 mips_print_operand_punct
['*'] = TRUE
;
2901 mips_print_operand_punct
['@'] = TRUE
;
2902 mips_print_operand_punct
['.'] = TRUE
;
2903 mips_print_operand_punct
['('] = TRUE
;
2904 mips_print_operand_punct
[')'] = TRUE
;
2905 mips_print_operand_punct
['['] = TRUE
;
2906 mips_print_operand_punct
[']'] = TRUE
;
2907 mips_print_operand_punct
['<'] = TRUE
;
2908 mips_print_operand_punct
['>'] = TRUE
;
2909 mips_print_operand_punct
['{'] = TRUE
;
2910 mips_print_operand_punct
['}'] = TRUE
;
2912 mips_char_to_class
['d'] = GR_REGS
;
2913 mips_char_to_class
['f'] = ((TARGET_HARD_FLOAT
) ? FP_REGS
: NO_REGS
);
2914 mips_char_to_class
['h'] = HI_REG
;
2915 mips_char_to_class
['l'] = LO_REG
;
2916 mips_char_to_class
['x'] = MD_REGS
;
2917 mips_char_to_class
['y'] = GR_REGS
;
2918 mips_char_to_class
['z'] = ST_REGS
;
2920 /* Set up array to map GCC register number to debug register number.
2921 Ignore the special purpose register numbers. */
2923 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2924 mips_dbx_regno
[i
] = -1;
2926 start
= GP_DBX_FIRST
- GP_REG_FIRST
;
2927 for (i
= GP_REG_FIRST
; i
<= GP_REG_LAST
; i
++)
2928 mips_dbx_regno
[i
] = i
+ start
;
2930 start
= FP_DBX_FIRST
- FP_REG_FIRST
;
2931 for (i
= FP_REG_FIRST
; i
<= FP_REG_LAST
; i
++)
2932 mips_dbx_regno
[i
] = i
+ start
;
2934 /* Set up array giving whether a given register can hold a given mode.
2935 At present, restrict ints from being in FP registers, because reload
2936 is a little enthusiastic about storing extra values in FP registers,
2937 and this is not good for things like OS kernels. Also, due to the
2938 mandatory delay, it is as fast to load from cached memory as to move
2939 from the FP register. */
2941 for (mode
= VOIDmode
;
2942 mode
!= MAX_MACHINE_MODE
;
2943 mode
= (enum machine_mode
)((int)mode
+ 1))
2945 register int size
= GET_MODE_SIZE (mode
);
2946 register enum mode_class
class = GET_MODE_CLASS (mode
);
2948 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
2952 if (mode
== CC_FPmode
|| mode
== CC_REV_FPmode
)
2953 temp
= (regno
== FPSW_REGNUM
);
2955 else if (GP_REG_P (regno
))
2956 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
2958 else if (FP_REG_P (regno
))
2959 temp
= ((TARGET_FLOAT64
|| ((regno
& 1) == 0))
2960 && (class == MODE_FLOAT
2961 || class == MODE_COMPLEX_FLOAT
2962 || (TARGET_DEBUG_H_MODE
&& class == MODE_INT
)));
2964 else if (MD_REG_P (regno
))
2965 temp
= (mode
== SImode
|| (regno
== MD_REG_FIRST
&& mode
== DImode
));
2970 mips_hard_regno_mode_ok
[(int)mode
][regno
] = temp
;
2977 * The MIPS debug format wants all automatic variables and arguments
2978 * to be in terms of the virtual frame pointer (stack pointer before
2979 * any adjustment in the function), while the MIPS 3.0 linker wants
2980 * the frame pointer to be the stack pointer after the initial
2981 * adjustment. So, we do the adjustment here. The arg pointer (which
2982 * is eliminated) points to the virtual frame pointer, while the frame
2983 * pointer (which may be eliminated) points to the stack pointer after
2984 * the initial adjustments.
2988 mips_debugger_offset (addr
, offset
)
2992 rtx offset2
= const0_rtx
;
2993 rtx reg
= eliminate_constant_term (addr
, &offset2
);
2996 offset
= INTVAL (offset2
);
2998 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
)
3000 int frame_size
= (!current_frame_info
.initialized
)
3001 ? compute_frame_size (get_frame_size ())
3002 : current_frame_info
.total_size
;
3004 offset
= offset
- frame_size
;
3006 else if (reg
!= arg_pointer_rtx
)
3007 abort_with_insn (addr
, "mips_debugger_offset called with non stack/frame/arg pointer.");
3013 /* A C compound statement to output to stdio stream STREAM the
3014 assembler syntax for an instruction operand X. X is an RTL
3017 CODE is a value that can be used to specify one of several ways
3018 of printing the operand. It is used when identical operands
3019 must be printed differently depending on the context. CODE
3020 comes from the `%' specification that was used to request
3021 printing of the operand. If the specification was just `%DIGIT'
3022 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3023 is the ASCII code for LTR.
3025 If X is a register, this macro should print the register's name.
3026 The names can be found in an array `reg_names' whose type is
3027 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3029 When the machine description has a specification `%PUNCT' (a `%'
3030 followed by a punctuation character), this macro is called with
3031 a null pointer for X and the punctuation character for CODE.
3033 The MIPS specific codes are:
3035 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
3036 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
3037 'd' output integer constant in decimal,
3038 'z' if the operand is 0, use $0 instead of normal operand.
3039 'D' print second register of double-word register operand.
3040 'L' print low-order register of double-word register operand.
3041 'M' print high-order register of double-word register operand.
3042 'C' print part of opcode for a branch condition.
3043 'N' print part of opcode for a branch condition, inverted.
3044 '(' Turn on .set noreorder
3045 ')' Turn on .set reorder
3046 '[' Turn on .set noat
3048 '<' Turn on .set nomacro
3049 '>' Turn on .set macro
3050 '{' Turn on .set volatile (not GAS)
3051 '}' Turn on .set novolatile (not GAS)
3052 '&' Turn on .set noreorder if filling delay slots
3053 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
3054 '!' Turn on .set nomacro if filling delay slots
3055 '#' Print nop if in a .set noreorder section.
3056 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3057 '@' Print the name of the assembler temporary register (at or $1).
3058 '.' Print the name of the register with a hard-wired zero (zero or $0). */
3061 print_operand (file
, op
, letter
)
3062 FILE *file
; /* file to write to */
3063 rtx op
; /* operand to print */
3064 int letter
; /* %<letter> or 0 */
3066 register enum rtx_code code
;
3068 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3073 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3077 if (mips_branch_likely
)
3082 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3086 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3090 if (final_sequence
!= 0 && set_noreorder
++ == 0)
3091 fputs (".set\tnoreorder\n\t", file
);
3095 if (final_sequence
!= 0)
3097 if (set_noreorder
++ == 0)
3098 fputs (".set\tnoreorder\n\t", file
);
3100 if (set_nomacro
++ == 0)
3101 fputs (".set\tnomacro\n\t", file
);
3106 if (final_sequence
!= 0 && set_nomacro
++ == 0)
3107 fputs ("\n\t.set\tnomacro", file
);
3111 if (set_noreorder
!= 0)
3112 fputs ("\n\tnop", file
);
3114 else if (TARGET_GAS
|| TARGET_STATS
)
3115 fputs ("\n\t#nop", file
);
3120 if (set_noreorder
++ == 0)
3121 fputs (".set\tnoreorder\n\t", file
);
3125 if (set_noreorder
== 0)
3126 error ("internal error: %%) found without a %%( in assembler pattern");
3128 else if (--set_noreorder
== 0)
3129 fputs ("\n\t.set\treorder", file
);
3134 if (set_noat
++ == 0)
3135 fputs (".set\tnoat\n\t", file
);
3140 error ("internal error: %%] found without a %%[ in assembler pattern");
3142 else if (--set_noat
== 0)
3143 fputs ("\n\t.set\tat", file
);
3148 if (set_nomacro
++ == 0)
3149 fputs (".set\tnomacro\n\t", file
);
3153 if (set_nomacro
== 0)
3154 error ("internal error: %%> found without a %%< in assembler pattern");
3156 else if (--set_nomacro
== 0)
3157 fputs ("\n\t.set\tmacro", file
);
3162 if (set_volatile
++ == 0)
3163 fprintf (file
, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS
) ? "" : "#");
3167 if (set_volatile
== 0)
3168 error ("internal error: %%} found without a %%{ in assembler pattern");
3170 else if (--set_volatile
== 0)
3171 fprintf (file
, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS
) ? "" : "#");
3180 error ("PRINT_OPERAND null pointer");
3184 code
= GET_CODE (op
);
3188 case EQ
: fputs ("eq", file
); break;
3189 case NE
: fputs ("ne", file
); break;
3190 case GT
: fputs ("gt", file
); break;
3191 case GE
: fputs ("ge", file
); break;
3192 case LT
: fputs ("lt", file
); break;
3193 case LE
: fputs ("le", file
); break;
3194 case GTU
: fputs ("gtu", file
); break;
3195 case GEU
: fputs ("geu", file
); break;
3196 case LTU
: fputs ("ltu", file
); break;
3197 case LEU
: fputs ("leu", file
); break;
3200 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%C");
3203 else if (letter
== 'N')
3206 case EQ
: fputs ("ne", file
); break;
3207 case NE
: fputs ("eq", file
); break;
3208 case GT
: fputs ("le", file
); break;
3209 case GE
: fputs ("lt", file
); break;
3210 case LT
: fputs ("ge", file
); break;
3211 case LE
: fputs ("gt", file
); break;
3212 case GTU
: fputs ("leu", file
); break;
3213 case GEU
: fputs ("ltu", file
); break;
3214 case LTU
: fputs ("geu", file
); break;
3215 case LEU
: fputs ("gtu", file
); break;
3218 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%N");
3221 else if (code
== REG
)
3223 register int regnum
= REGNO (op
);
3226 regnum
+= MOST_SIGNIFICANT_WORD
;
3228 else if (letter
== 'L')
3229 regnum
+= LEAST_SIGNIFICANT_WORD
;
3231 else if (letter
== 'D')
3234 fprintf (file
, "%s", reg_names
[regnum
]);
3237 else if (code
== MEM
)
3238 output_address (XEXP (op
, 0));
3240 else if (code
== CONST_DOUBLE
)
3242 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
3243 union { double d
; int i
[2]; } u
;
3244 u
.i
[0] = CONST_DOUBLE_LOW (op
);
3245 u
.i
[1] = CONST_DOUBLE_HIGH (op
);
3246 if (GET_MODE (op
) == SFmode
)
3252 fprintf (file
, "%.20e", u
.d
);
3254 fatal ("CONST_DOUBLE found in cross compilation");
3258 else if ((letter
== 'x') && (GET_CODE(op
) == CONST_INT
))
3259 fprintf (file
, "0x%04x", 0xffff & (INTVAL(op
)));
3261 else if ((letter
== 'X') && (GET_CODE(op
) == CONST_INT
))
3262 fprintf (file
, "0x%08x", INTVAL(op
));
3264 else if ((letter
== 'd') && (GET_CODE(op
) == CONST_INT
))
3265 fprintf (file
, "%d", (INTVAL(op
)));
3267 else if (letter
== 'z'
3268 && (GET_CODE (op
) == CONST_INT
)
3269 && INTVAL (op
) == 0)
3270 fputs (reg_names
[GP_REG_FIRST
], file
);
3272 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3273 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter
);
3276 output_addr_const (file
, op
);
3280 /* A C compound statement to output to stdio stream STREAM the
3281 assembler syntax for an instruction operand that is a memory
3282 reference whose address is ADDR. ADDR is an RTL expression.
3284 On some machines, the syntax for a symbolic address depends on
3285 the section that the address refers to. On these machines,
3286 define the macro `ENCODE_SECTION_INFO' to store the information
3287 into the `symbol_ref', and then check for it here. */
3290 print_operand_address (file
, addr
)
3295 error ("PRINT_OPERAND_ADDRESS, null pointer");
3298 switch (GET_CODE (addr
))
3301 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #1");
3305 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3306 abort_with_insn (addr
, "Arg pointer not eliminated.");
3308 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
3313 register rtx reg
= (rtx
)0;
3314 register rtx offset
= (rtx
)0;
3315 register rtx arg0
= XEXP (addr
, 0);
3316 register rtx arg1
= XEXP (addr
, 1);
3318 if (GET_CODE (arg0
) == REG
)
3322 if (GET_CODE (offset
) == REG
)
3323 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
3325 else if (GET_CODE (arg1
) == REG
)
3330 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
3332 output_addr_const (file
, addr
);
3336 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3338 if (!CONSTANT_P (offset
))
3339 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #2");
3341 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3342 abort_with_insn (addr
, "Arg pointer not eliminated.");
3344 output_addr_const (file
, offset
);
3345 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3353 output_addr_const (file
, addr
);
3359 /* If optimizing for the global pointer, keep track of all of
3360 the externs, so that at the end of the file, we can emit
3361 the appropriate .extern declaration for them, before writing
3362 out the text section. We assume that all names passed to
3363 us are in the permanent obstack, so that they will be valid
3364 at the end of the compilation.
3366 If we have -G 0, or the extern size is unknown, don't bother
3367 emitting the .externs. */
3370 mips_output_external (file
, decl
, name
)
3375 register struct extern_list
*p
;
3379 && mips_section_threshold
!= 0
3380 && ((TREE_CODE (decl
)) != FUNCTION_DECL
)
3381 && ((len
= int_size_in_bytes (TREE_TYPE (decl
))) > 0))
3383 p
= (struct extern_list
*)permalloc ((long) sizeof (struct extern_list
));
3384 p
->next
= extern_head
;
3393 /* Compute a string to use as a temporary file name. */
3399 char *base
= getenv ("TMPDIR");
3402 if (base
== (char *)0)
3405 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
3409 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
3415 len
= strlen (base
);
3416 temp_filename
= (char *) alloca (len
+ sizeof("/ccXXXXXX"));
3417 strcpy (temp_filename
, base
);
3418 if (len
> 0 && temp_filename
[len
-1] != '/')
3419 temp_filename
[len
++] = '/';
3421 strcpy (temp_filename
+ len
, "ccXXXXXX");
3422 mktemp (temp_filename
);
3424 stream
= fopen (temp_filename
, "w+");
3426 pfatal_with_name (temp_filename
);
3428 unlink (temp_filename
);
3433 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out
3434 for .file's that start within a function. If we are smuggling stabs, try to
3435 put out a MIPS ECOFF file and a stab. */
3438 mips_output_filename (stream
, name
)
3442 static int first_time
= TRUE
;
3443 char ltext_label_name
[100];
3449 current_function_file
= name
;
3450 fprintf (stream
, "\t.file\t%d \"%s\"\n", num_source_filenames
, name
);
3451 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3452 fprintf (stream
, "\t#@stabs\n");
3455 else if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3457 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
3458 fprintf (stream
, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP
,
3459 name
, N_SOL
, <ext_label_name
[1]);
3462 else if (name
!= current_function_file
3463 && strcmp (name
, current_function_file
) != 0)
3465 if (inside_function
&& !TARGET_GAS
)
3467 if (!file_in_function_warning
)
3469 file_in_function_warning
= TRUE
;
3470 ignore_line_number
= TRUE
;
3471 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line");
3474 fprintf (stream
, "\t#.file\t%d \"%s\"\n", num_source_filenames
, name
);
3480 current_function_file
= name
;
3481 fprintf (stream
, "\t.file\t%d \"%s\"\n", num_source_filenames
, name
);
3487 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
3488 as well as a .loc, since it is possible that MIPS ECOFF might not be
3489 able to represent the location for inlines that come from a different
3493 mips_output_lineno (stream
, line
)
3497 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3500 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3501 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
3506 fprintf (stream
, "\n\t%s.loc\t%d %d\n",
3507 (ignore_line_number
) ? "#" : "",
3508 num_source_filenames
, line
);
3510 LABEL_AFTER_LOC (stream
);
3515 /* If defined, a C statement to be executed just prior to the
3516 output of assembler code for INSN, to modify the extracted
3517 operands so they will be output differently.
3519 Here the argument OPVEC is the vector containing the operands
3520 extracted from INSN, and NOPERANDS is the number of elements of
3521 the vector which contain meaningful data for this insn. The
3522 contents of this vector are what will be used to convert the
3523 insn template into assembler code, so you can change the
3524 assembler output by changing the contents of the vector.
3526 We use it to check if the current insn needs a nop in front of it
3527 because of load delays, and also to update the delay slot
3531 final_prescan_insn (insn
, opvec
, noperands
)
3536 if (dslots_number_nops
> 0)
3538 rtx pattern
= PATTERN (insn
);
3539 int length
= get_attr_length (insn
);
3541 /* Do we need to emit a NOP? */
3543 || (mips_load_reg
!= (rtx
)0 && reg_mentioned_p (mips_load_reg
, pattern
))
3544 || (mips_load_reg2
!= (rtx
)0 && reg_mentioned_p (mips_load_reg2
, pattern
))
3545 || (mips_load_reg3
!= (rtx
)0 && reg_mentioned_p (mips_load_reg3
, pattern
))
3546 || (mips_load_reg4
!= (rtx
)0 && reg_mentioned_p (mips_load_reg4
, pattern
)))
3547 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
3550 dslots_load_filled
++;
3552 while (--dslots_number_nops
> 0)
3553 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
3555 mips_load_reg
= (rtx
)0;
3556 mips_load_reg2
= (rtx
)0;
3557 mips_load_reg3
= (rtx
)0;
3558 mips_load_reg4
= (rtx
)0;
3560 if (set_noreorder
&& --set_noreorder
== 0)
3561 fputs ("\t.set\treorder\n", asm_out_file
);
3566 enum rtx_code code
= GET_CODE (insn
);
3567 if (code
== JUMP_INSN
|| code
== CALL_INSN
)
3568 dslots_jump_total
++;
3573 /* Output at beginning of assembler file.
3574 If we are optimizing to use the global pointer, create a temporary
3575 file to hold all of the text stuff, and write it out to the end.
3576 This is needed because the MIPS assembler is evidently one pass,
3577 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata
3578 declaration when the code is processed, it generates a two
3579 instruction sequence. */
3582 mips_asm_file_start (stream
)
3585 ASM_OUTPUT_SOURCE_FILENAME (stream
, main_input_filename
);
3587 /* Versions of the MIPS assembler before 2.20 generate errors
3588 if a branch inside of a .set noreorder section jumps to a
3589 label outside of the .set noreorder section. Revision 2.20
3590 just set nobopt silently rather than fixing the bug. */
3592 if (TARGET_MIPS_AS
&& optimize
&& flag_delayed_branch
)
3593 fprintf (stream
, "\t.set\tnobopt\n");
3595 /* Generate the pseudo ops that the Pyramid based System V.4 wants. */
3596 if (TARGET_ABICALLS
)
3597 fprintf (stream
, "\t.abicalls\n");
3601 asm_out_data_file
= stream
;
3602 asm_out_text_file
= make_temp_file ();
3605 asm_out_data_file
= asm_out_text_file
= stream
;
3607 if (TARGET_NAME_REGS
)
3608 fprintf (asm_out_file
, "#include <regdef.h>\n");
3610 print_options (stream
);
3614 /* If we are optimizing the global pointer, emit the text section now
3615 and any small externs which did not have .comm, etc that are
3616 needed. Also, give a warning if the data area is more than 32K and
3617 -pic because 3 instructions are needed to reference the data
3621 mips_asm_file_end (file
)
3626 struct extern_list
*p
;
3630 HALF_PIC_FINISH (file
);
3637 for (p
= extern_head
; p
!= 0; p
= p
->next
)
3639 name_tree
= get_identifier (p
->name
);
3641 /* Positively ensure only one .extern for any given symbol. */
3642 if (! TREE_ASM_WRITTEN (name_tree
))
3644 TREE_ASM_WRITTEN (name_tree
) = 1;
3645 fputs ("\t.extern\t", file
);
3646 assemble_name (file
, p
->name
);
3647 fprintf (file
, ", %d\n", p
->size
);
3651 fprintf (file
, "\n\t.text\n");
3652 rewind (asm_out_text_file
);
3653 if (ferror (asm_out_text_file
))
3654 fatal_io_error (temp_filename
);
3656 while ((len
= fread (buffer
, 1, sizeof (buffer
), asm_out_text_file
)) > 0)
3657 if (fwrite (buffer
, 1, len
, file
) != len
)
3658 pfatal_with_name (asm_file_name
);
3661 pfatal_with_name (temp_filename
);
3663 if (fclose (asm_out_text_file
) != 0)
3664 pfatal_with_name (temp_filename
);
3669 /* Emit either a label, .comm, or .lcomm directive, and mark
3670 that the symbol is used, so that we don't emit an .extern
3671 for it in mips_asm_file_end. */
3674 mips_declare_object (stream
, name
, init_string
, final_string
, size
)
3681 fputs (init_string
, stream
); /* "", "\t.comm\t", or "\t.lcomm\t" */
3682 assemble_name (stream
, name
);
3683 fprintf (stream
, final_string
, size
); /* ":\n", ",%u\n", ",%u\n" */
3685 if (TARGET_GP_OPT
&& mips_section_threshold
!= 0)
3687 tree name_tree
= get_identifier (name
);
3688 TREE_ASM_WRITTEN (name_tree
) = 1;
3693 /* Output a double precision value to the assembler. If both the
3694 host and target are IEEE, emit the values in hex. */
3697 mips_output_double (stream
, value
)
3699 REAL_VALUE_TYPE value
;
3701 #ifdef REAL_VALUE_TO_TARGET_DOUBLE
3703 REAL_VALUE_TO_TARGET_DOUBLE (value
, value_long
);
3705 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n",
3706 value_long
[0], value
, value_long
[1]);
3708 fprintf (stream
, "\t.double\t%.20g\n", value
);
3713 /* Output a single precision value to the assembler. If both the
3714 host and target are IEEE, emit the values in hex. */
3717 mips_output_float (stream
, value
)
3719 REAL_VALUE_TYPE value
;
3721 #ifdef REAL_VALUE_TO_TARGET_SINGLE
3723 REAL_VALUE_TO_TARGET_SINGLE (value
, value_long
);
3725 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long
, value
);
3727 fprintf (stream
, "\t.float\t%.12g\n", value
);
3732 /* Return the bytes needed to compute the frame pointer from the current
3735 Mips stack frames look like:
3737 Before call After call
3738 +-----------------------+ +-----------------------+
3741 | caller's temps. | | caller's temps. |
3743 +-----------------------+ +-----------------------+
3745 | arguments on stack. | | arguments on stack. |
3747 +-----------------------+ +-----------------------+
3748 | 4 words to save | | 4 words to save |
3749 | arguments passed | | arguments passed |
3750 | in registers, even | | in registers, even |
3751 SP->| if not passed. | FP->| if not passed. |
3752 +-----------------------+ +-----------------------+
3754 | GP save for V.4 abi |
3756 +-----------------------+
3758 | fp register save |
3760 +-----------------------+
3762 | gp register save |
3764 +-----------------------+
3768 +-----------------------+
3770 | alloca allocations |
3772 +-----------------------+
3774 | arguments on stack |
3776 +-----------------------+
3778 | arguments passed |
3779 | in registers, even |
3780 low SP->| if not passed. |
3781 memory +-----------------------+
3786 compute_frame_size (size
)
3787 int size
; /* # of var. bytes allocated */
3790 unsigned long total_size
; /* # bytes that the entire frame takes up */
3791 unsigned long var_size
; /* # bytes that variables take up */
3792 unsigned long args_size
; /* # bytes that outgoing arguments take up */
3793 unsigned long extra_size
; /* # extra bytes */
3794 unsigned int gp_reg_rounded
; /* # bytes needed to store gp after rounding */
3795 unsigned int gp_reg_size
; /* # bytes needed to store gp regs */
3796 unsigned int fp_reg_size
; /* # bytes needed to store fp regs */
3797 unsigned long mask
; /* mask of saved gp registers */
3798 unsigned long fmask
; /* mask of saved fp registers */
3799 int fp_inc
; /* 1 or 2 depending on the size of fp regs */
3800 int fp_bits
; /* bitmask to use for each fp register */
3806 extra_size
= MIPS_STACK_ALIGN (((TARGET_ABICALLS
) ? UNITS_PER_WORD
: 0));
3807 var_size
= MIPS_STACK_ALIGN (size
);
3808 args_size
= MIPS_STACK_ALIGN (current_function_outgoing_args_size
);
3810 /* The MIPS 3.0 linker does not like functions that dynamically
3811 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
3812 looks like we are trying to create a second frame pointer to the
3813 function, so allocate some stack space to make it happy. */
3815 if (args_size
== 0 && current_function_calls_alloca
)
3816 args_size
= 4*UNITS_PER_WORD
;
3818 total_size
= var_size
+ args_size
+ extra_size
;
3820 /* Calculate space needed for gp registers. */
3821 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
3823 if (MUST_SAVE_REGISTER (regno
))
3825 gp_reg_size
+= UNITS_PER_WORD
;
3826 mask
|= 1 << (regno
- GP_REG_FIRST
);
3830 /* Calculate space needed for fp registers. */
3842 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
+= fp_inc
)
3844 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
3846 fp_reg_size
+= 2*UNITS_PER_WORD
;
3847 fmask
|= fp_bits
<< (regno
- FP_REG_FIRST
);
3851 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
3852 total_size
+= gp_reg_rounded
+ fp_reg_size
;
3854 if (total_size
== extra_size
)
3855 total_size
= extra_size
= 0;
3857 /* Save other computed information. */
3858 current_frame_info
.total_size
= total_size
;
3859 current_frame_info
.var_size
= var_size
;
3860 current_frame_info
.args_size
= args_size
;
3861 current_frame_info
.extra_size
= extra_size
;
3862 current_frame_info
.gp_reg_size
= gp_reg_size
;
3863 current_frame_info
.fp_reg_size
= fp_reg_size
;
3864 current_frame_info
.mask
= mask
;
3865 current_frame_info
.fmask
= fmask
;
3866 current_frame_info
.initialized
= reload_completed
;
3867 current_frame_info
.num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
3868 current_frame_info
.num_fp
= fp_reg_size
/ (2*UNITS_PER_WORD
);
3872 unsigned long offset
= args_size
+ var_size
+ gp_reg_size
- UNITS_PER_WORD
;
3873 current_frame_info
.gp_sp_offset
= offset
;
3874 current_frame_info
.gp_save_offset
= offset
- total_size
;
3878 current_frame_info
.gp_sp_offset
= 0;
3879 current_frame_info
.gp_save_offset
= 0;
3885 unsigned long offset
= args_size
+ var_size
+ gp_reg_rounded
+ fp_reg_size
- 2*UNITS_PER_WORD
;
3886 current_frame_info
.fp_sp_offset
= offset
;
3887 current_frame_info
.fp_save_offset
= offset
- total_size
+ UNITS_PER_WORD
;
3891 current_frame_info
.fp_sp_offset
= 0;
3892 current_frame_info
.fp_save_offset
= 0;
3895 /* Ok, we're done. */
3900 /* Save/restore registers printing out the instructions to a file. */
3903 save_restore (file
, gp_op
, gp_2word_op
, fp_op
)
3904 FILE *file
; /* stream to write to */
3905 char *gp_op
; /* operation to do on gp registers */
3906 char *gp_2word_op
; /* 2 word op to do on gp registers */
3907 char *fp_op
; /* operation to do on fp registers */
3910 unsigned long mask
= current_frame_info
.mask
;
3911 unsigned long fmask
= current_frame_info
.fmask
;
3912 unsigned long gp_offset
;
3913 unsigned long fp_offset
;
3914 unsigned long max_offset
;
3917 if (mask
== 0 && fmask
== 0)
3920 base_reg
= reg_names
[STACK_POINTER_REGNUM
];
3921 gp_offset
= current_frame_info
.gp_sp_offset
;
3922 fp_offset
= current_frame_info
.fp_sp_offset
;
3923 max_offset
= (gp_offset
> fp_offset
) ? gp_offset
: fp_offset
;
3925 /* Deal with calling functions with a large structure. */
3926 if (max_offset
>= 32768)
3928 char *temp
= reg_names
[MIPS_TEMP2_REGNUM
];
3929 fprintf (file
, "\tli\t%s,%ld\n", temp
, max_offset
);
3930 fprintf (file
, "\taddu\t%s,%s,%s\n", temp
, temp
, base_reg
);
3932 gp_offset
= max_offset
- gp_offset
;
3933 fp_offset
= max_offset
- fp_offset
;
3936 /* Save registers starting from high to low. The debuggers prefer
3937 at least the return register be stored at func+4, and also it
3938 allows us not to need a nop in the epilog if at least one
3939 register is reloaded in addition to return address. */
3941 if (mask
|| frame_pointer_needed
)
3943 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
3945 if ((mask
& (1L << (regno
- GP_REG_FIRST
))) != 0
3946 || (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
))
3948 fprintf (file
, "\t%s\t%s,%d(%s)\n",
3949 gp_op
, reg_names
[regno
],
3950 gp_offset
, base_reg
);
3952 gp_offset
-= UNITS_PER_WORD
;
3959 int fp_inc
= (TARGET_FLOAT64
) ? 1 : 2;
3961 for (regno
= FP_REG_LAST
-1; regno
>= FP_REG_FIRST
; regno
-= fp_inc
)
3963 if ((fmask
& (1L << (regno
- FP_REG_FIRST
))) != 0)
3965 fprintf (file
, "\t%s\t%s,%d(%s)\n",
3966 fp_op
, reg_names
[regno
], fp_offset
, base_reg
);
3968 fp_offset
-= 2*UNITS_PER_WORD
;
3975 /* Common code to emit the insns to save/restore registers. */
3978 save_restore_insns (store_p
)
3979 int store_p
; /* true if this is prologue */
3982 rtx base_reg_rtx
= stack_pointer_rtx
;
3983 unsigned long mask
= current_frame_info
.mask
;
3984 unsigned long fmask
= current_frame_info
.fmask
;
3985 unsigned long gp_offset
;
3986 unsigned long fp_offset
;
3987 unsigned long max_offset
;
3989 if (mask
== 0 && fmask
== 0)
3992 gp_offset
= current_frame_info
.gp_sp_offset
;
3993 fp_offset
= current_frame_info
.fp_sp_offset
;
3994 max_offset
= (gp_offset
> fp_offset
) ? gp_offset
: fp_offset
;
3996 /* Deal with calling functions with a large structure. */
3997 if (max_offset
>= 32768)
3999 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4000 emit_move_insn (base_reg_rtx
, GEN_INT (max_offset
));
4001 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4002 gp_offset
= max_offset
- gp_offset
;
4003 fp_offset
= max_offset
- fp_offset
;
4006 /* Save registers starting from high to low. The debuggers prefer
4007 at least the return register be stored at func+4, and also it
4008 allows us not to need a nop in the epilog if at least one
4009 register is reloaded in addition to return address. */
4011 if (mask
|| frame_pointer_needed
)
4013 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
4015 if ((mask
& (1L << (regno
- GP_REG_FIRST
))) != 0
4016 || (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
))
4018 rtx reg_rtx
= gen_rtx (REG
, Pmode
, regno
);
4019 rtx mem_rtx
= gen_rtx (MEM
, Pmode
,
4020 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4021 GEN_INT (gp_offset
)));
4024 emit_move_insn (mem_rtx
, reg_rtx
);
4026 emit_move_insn (reg_rtx
, mem_rtx
);
4028 gp_offset
-= UNITS_PER_WORD
;
4035 int fp_inc
= (TARGET_FLOAT64
) ? 1 : 2;
4037 for (regno
= FP_REG_LAST
-1; regno
>= FP_REG_FIRST
; regno
-= fp_inc
)
4039 if ((fmask
& (1L << (regno
- FP_REG_FIRST
))) != 0)
4041 rtx reg_rtx
= gen_rtx (REG
, DFmode
, regno
);
4042 rtx mem_rtx
= gen_rtx (MEM
, DFmode
,
4043 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4044 GEN_INT (fp_offset
)));
4047 emit_move_insn (mem_rtx
, reg_rtx
);
4049 emit_move_insn (reg_rtx
, mem_rtx
);
4051 fp_offset
-= 2*UNITS_PER_WORD
;
4058 /* Set up the stack and frame (if desired) for the function. */
4061 function_prologue (file
, size
)
4065 int tsize
= current_frame_info
.total_size
;
4067 ASM_OUTPUT_SOURCE_FILENAME (file
, DECL_SOURCE_FILE (current_function_decl
));
4068 ASM_OUTPUT_SOURCE_LINE (file
, DECL_SOURCE_LINE (current_function_decl
));
4070 inside_function
= 1;
4071 fputs ("\t.ent\t", file
);
4072 assemble_name (file
, current_function_name
);
4074 assemble_name (file
, current_function_name
);
4075 fputs (":\n", file
);
4077 if (TARGET_ABICALLS
)
4079 "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
4080 reg_names
[ GP_REG_FIRST
+ 25 ]);
4082 tsize
= current_frame_info
.total_size
;
4083 if (tsize
> 0 && TARGET_ABICALLS
)
4084 fprintf (file
, "\t.cprestore %d\n", tsize
+ STARTING_FRAME_OFFSET
);
4086 fprintf (file
, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args = %d, extra= %d\n",
4087 reg_names
[ (frame_pointer_needed
) ? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
],
4089 reg_names
[31 + GP_REG_FIRST
],
4090 current_frame_info
.var_size
,
4091 current_frame_info
.num_gp
,
4092 current_frame_info
.num_fp
,
4093 current_function_outgoing_args_size
,
4094 current_frame_info
.extra_size
);
4096 fprintf (file
, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n",
4097 current_frame_info
.mask
,
4098 current_frame_info
.gp_save_offset
,
4099 current_frame_info
.fmask
,
4100 current_frame_info
.fp_save_offset
);
4104 /* Expand the prologue into a bunch of separate insns. */
4107 mips_expand_prologue ()
4111 tree fndecl
= current_function_decl
; /* current... is tooo long */
4112 tree fntype
= TREE_TYPE (fndecl
);
4113 tree fnargs
= (TREE_CODE (fntype
) != METHOD_TYPE
)
4114 ? DECL_ARGUMENTS (fndecl
)
4118 char *arg_name
= (char *)0;
4119 CUMULATIVE_ARGS args_so_far
;
4121 /* Determine the last argument, and get its name. */
4122 for (cur_arg
= fnargs
; cur_arg
!= (tree
)0; cur_arg
= next_arg
)
4124 next_arg
= TREE_CHAIN (cur_arg
);
4125 if (next_arg
== (tree
)0)
4127 if (DECL_NAME (cur_arg
))
4128 arg_name
= IDENTIFIER_POINTER (DECL_NAME (cur_arg
));
4134 /* If this function is a varargs function, store any registers that
4135 would normally hold arguments ($4 - $7) on the stack. */
4136 if ((TYPE_ARG_TYPES (fntype
) != 0
4137 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
))) != void_type_node
))
4139 && (strcmp (arg_name
, "__builtin_va_alist") == 0
4140 || strcmp (arg_name
, "va_alist") == 0)))
4144 regno
= GP_ARG_FIRST
;
4145 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, (rtx
)0);
4147 for (parm
= fnargs
; (parm
&& (regno
<= GP_ARG_LAST
)); parm
= TREE_CHAIN (parm
))
4150 enum machine_mode passed_mode
;
4153 type
= DECL_ARG_TYPE (parm
);
4154 passed_mode
= TYPE_MODE (type
);
4155 entry_parm
= FUNCTION_ARG (args_so_far
, passed_mode
,
4156 DECL_ARG_TYPE (parm
), 1);
4162 /* passed in a register, so will get homed automatically */
4163 if (GET_MODE (entry_parm
) == BLKmode
)
4164 words
= (int_size_in_bytes (type
) + 3) / 4;
4166 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
4168 regno
= REGNO (entry_parm
) + words
- 1;
4172 regno
= GP_ARG_LAST
+1;
4176 FUNCTION_ARG_ADVANCE (args_so_far
, passed_mode
,
4177 DECL_ARG_TYPE (parm
), 1);
4180 for (; regno
<= GP_ARG_LAST
; regno
++)
4182 rtx ptr
= stack_pointer_rtx
;
4183 if (regno
!= GP_ARG_FIRST
)
4184 ptr
= gen_rtx (PLUS
, Pmode
, ptr
,
4185 GEN_INT ((regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
));
4187 emit_move_insn (gen_rtx (MEM
, Pmode
, ptr
), gen_rtx (REG
, Pmode
, regno
));
4191 tsize
= compute_frame_size (get_frame_size ());
4194 rtx tsize_rtx
= GEN_INT (tsize
);
4198 rtx tmp_rtx
= gen_rtx (REG
, SImode
, MIPS_TEMP1_REGNUM
);
4199 emit_move_insn (tmp_rtx
, tsize_rtx
);
4200 tsize_rtx
= tmp_rtx
;
4203 emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
, tsize_rtx
));
4205 save_restore_insns (TRUE
);
4207 if (frame_pointer_needed
)
4208 emit_insn (gen_movsi (frame_pointer_rtx
, stack_pointer_rtx
));
4213 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */
4216 function_epilogue (file
, size
)
4221 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4222 char *t1_str
= reg_names
[MIPS_TEMP1_REGNUM
];
4223 rtx epilogue_delay
= current_function_epilogue_delay_list
;
4224 int noreorder
= !TARGET_MIPS_AS
|| (epilogue_delay
!= 0);
4225 int noepilogue
= FALSE
;
4226 int load_nop
= FALSE
;
4229 /* The epilogue does not depend on any registers, but the stack
4230 registers, so we assume that if we have 1 pending nop, it can be
4231 ignored, and 2 it must be filled (2 nops occur for integer
4232 multiply and divide). */
4234 if (dslots_number_nops
> 0)
4236 if (dslots_number_nops
== 1)
4238 dslots_number_nops
= 0;
4239 dslots_load_filled
++;
4243 while (--dslots_number_nops
> 0)
4244 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
4247 if (set_noreorder
> 0 && --set_noreorder
== 0)
4248 fputs ("\t.set\treorder\n", file
);
4254 fputs ("\t.set\tat\n", file
);
4255 error ("internal gcc error: .set noat left on in epilogue");
4258 if (set_nomacro
!= 0)
4261 fputs ("\t.set\tmacro\n", file
);
4262 error ("internal gcc error: .set nomacro left on in epilogue");
4265 if (set_noreorder
!= 0)
4268 fputs ("\t.set\treorder\n", file
);
4269 error ("internal gcc error: .set noreorder left on in epilogue");
4272 if (set_volatile
!= 0)
4275 fprintf (file
, "\t#.set\tnovolatile\n", (TARGET_MIPS_AS
) ? "" : "#");
4276 error ("internal gcc error: .set volatile left on in epilogue");
4279 size
= MIPS_STACK_ALIGN (size
);
4280 tsize
= (!current_frame_info
.initialized
)
4281 ? compute_frame_size (size
)
4282 : current_frame_info
.total_size
;
4284 if (tsize
== 0 && epilogue_delay
== 0)
4286 rtx insn
= get_last_insn ();
4288 /* If the last insn was a BARRIER, we don't have to write any code
4289 because a jump (aka return) was put there. */
4290 if (GET_CODE (insn
) == NOTE
)
4291 insn
= prev_nonnote_insn (insn
);
4292 if (insn
&& GET_CODE (insn
) == BARRIER
)
4300 /* In the reload sequence, we don't need to fill the load delay
4301 slots for most of the loads, also see if we can fill the final
4302 delay slot if not otherwise filled by the reload sequence. */
4305 fprintf (file
, "\t.set\tnoreorder\n");
4308 fprintf (file
, "\tli\t%s,%d\n", t1_str
, tsize
);
4310 if (frame_pointer_needed
)
4311 fprintf (file
, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
4312 sp_str
, reg_names
[FRAME_POINTER_REGNUM
]);
4314 save_restore (file
, "lw", "ld", "l.d");
4316 load_only_r31
= (current_frame_info
.mask
== (1 << 31)
4317 && current_frame_info
.fmask
== 0);
4321 /* If the only register saved is the return address, we need a
4322 nop, unless we have an instruction to put into it. Otherwise
4323 we don't since reloading multiple registers doesn't reference
4324 the register being loaded. */
4329 final_scan_insn (XEXP (epilogue_delay
, 0),
4333 1); /* nopeepholes */
4336 fprintf (file
, "\tnop\n");
4341 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
4344 fprintf (file
, "\taddu\t%s,%s,%s\n", sp_str
, sp_str
, t1_str
);
4347 fprintf (file
, "\taddu\t%s,%s,%d\n", sp_str
, sp_str
, tsize
);
4349 else if (!load_only_r31
&& epilogue_delay
!= 0)
4350 final_scan_insn (XEXP (epilogue_delay
, 0),
4354 1); /* nopeepholes */
4356 fprintf (file
, "\t.set\treorder\n");
4362 fprintf (file
, "\taddu\t%s,%s,%s\n", sp_str
, sp_str
, t1_str
);
4365 fprintf (file
, "\taddu\t%s,%s,%d\n", sp_str
, sp_str
, tsize
);
4367 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
4371 fputs ("\t.end\t", file
);
4372 assemble_name (file
, current_function_name
);
4377 int num_gp_regs
= current_frame_info
.gp_reg_size
/ 4;
4378 int num_fp_regs
= current_frame_info
.fp_reg_size
/ 8;
4379 int num_regs
= num_gp_regs
+ num_fp_regs
;
4380 char *name
= current_function_name
;
4385 dslots_load_total
+= num_regs
;
4388 dslots_jump_total
++;
4392 dslots_load_filled
+= num_regs
;
4394 /* If the only register saved is the return register, we
4395 can't fill this register's delay slot. */
4397 if (load_only_r31
&& epilogue_delay
== 0)
4398 dslots_load_filled
--;
4400 if (tsize
> 0 || (!load_only_r31
&& epilogue_delay
!= 0))
4401 dslots_jump_filled
++;
4405 "%-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",
4407 (frame_pointer_needed
) ? 'y' : 'n',
4408 ((current_frame_info
.mask
& (1 << 31)) != 0) ? 'n' : 'y',
4409 (current_function_calls_alloca
) ? 'y' : 'n',
4410 (current_function_calls_setjmp
) ? 'y' : 'n',
4411 (long)current_frame_info
.total_size
,
4412 (long)current_function_outgoing_args_size
,
4413 num_gp_regs
, num_fp_regs
,
4414 dslots_load_total
, dslots_load_filled
,
4415 dslots_jump_total
, dslots_jump_filled
,
4416 num_refs
[0], num_refs
[1], num_refs
[2]);
4418 if (HALF_PIC_NUMBER_PTRS
> prev_half_pic_ptrs
)
4420 fprintf (stderr
, " half-pic=%3d", HALF_PIC_NUMBER_PTRS
- prev_half_pic_ptrs
);
4421 prev_half_pic_ptrs
= HALF_PIC_NUMBER_PTRS
;
4424 if (HALF_PIC_NUMBER_REFS
> prev_half_pic_refs
)
4426 fprintf (stderr
, " pic-ref=%3d", HALF_PIC_NUMBER_REFS
- prev_half_pic_refs
);
4427 prev_half_pic_refs
= HALF_PIC_NUMBER_REFS
;
4430 fputc ('\n', stderr
);
4433 /* Reset state info for each function. */
4434 inside_function
= FALSE
;
4435 ignore_line_number
= FALSE
;
4436 dslots_load_total
= 0;
4437 dslots_jump_total
= 0;
4438 dslots_load_filled
= 0;
4439 dslots_jump_filled
= 0;
4443 mips_load_reg
= (rtx
)0;
4444 mips_load_reg2
= (rtx
)0;
4445 current_frame_info
= zero_frame_info
;
4447 /* Restore the output file if optimizing the GP (optimizing the GP causes
4448 the text to be diverted to a tempfile, so that data decls come before
4449 references to the data). */
4452 asm_out_file
= asm_out_data_file
;
4456 /* Expand the epilogue into a bunch of separate insns. */
4459 mips_expand_epilogue ()
4461 int tsize
= current_frame_info
.total_size
;
4462 rtx tsize_rtx
= GEN_INT (tsize
);
4466 rtx tmp_rtx
= gen_rtx (REG
, SImode
, MIPS_TEMP1_REGNUM
);
4467 emit_move_insn (tmp_rtx
, tsize_rtx
);
4468 tsize_rtx
= tmp_rtx
;
4473 if (frame_pointer_needed
)
4474 emit_insn (gen_movsi (stack_pointer_rtx
, frame_pointer_rtx
));
4476 save_restore_insns (FALSE
);
4478 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
, tsize_rtx
));
4481 emit_jump_insn (gen_return_internal (gen_rtx (REG
, Pmode
, GP_REG_FIRST
+31)));
4485 /* Define the number of delay slots needed for the function epilogue.
4487 On the mips, we need a slot if either no stack has been allocated,
4488 or the only register saved is the return register. */
4491 mips_epilogue_delay_slots ()
4493 if (!current_frame_info
.initialized
)
4494 (void) compute_frame_size (get_frame_size ());
4496 if (current_frame_info
.total_size
== 0)
4499 if (current_frame_info
.mask
== (1 << 31) && current_frame_info
.fmask
== 0)
4506 /* Return true if this function is known to have a null epilogue.
4507 This allows the optimizer to omit jumps to jumps if no stack
4511 simple_epilogue_p ()
4513 if (!reload_completed
)
4516 if (current_frame_info
.initialized
)
4517 return current_frame_info
.total_size
== 0;
4519 return (compute_frame_size (get_frame_size ())) == 0;