1 /* Subroutines for insn-output.c for MIPS
2 Contributed by A. Lichnewsky, lich@inria.inria.fr.
3 Changes by Michael Meissner, meissner@osf.org.
4 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
5 Brendan Eich, brendan@microunity.com.
6 Copyright (C) 1989, 1990, 1991, 1993 Free Software Foundation, Inc.
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 /* ??? The TARGET_FP_CALL_32 macros are intended to simulate a 32 bit
25 calling convention in 64 bit mode. It doesn't work though, and should
26 be replaced with something better designed. */
31 #include "hard-reg-set.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "insn-flags.h"
36 #include "insn-attr.h"
37 #include "insn-codes.h"
41 #undef MAX /* sys/param.h may also define these */
46 #include <sys/types.h>
59 #if defined(USG) || defined(NO_STAB_H)
60 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
62 #include <stab.h> /* On BSD, use the system's stab.h. */
66 #define STAB_CODE_TYPE enum __stab_debug_code
68 #define STAB_CODE_TYPE int
73 extern char *getenv ();
74 extern char *mktemp ();
76 extern rtx
adj_offsettable_operand ();
77 extern rtx
copy_to_reg ();
80 extern tree
lookup_name ();
81 extern void pfatal_with_name ();
82 extern void warning ();
84 extern tree current_function_decl
;
85 extern FILE *asm_out_file
;
87 /* Enumeration for all of the relational tests, so that we can build
88 arrays indexed by the test type, and not worry about the order
105 /* Global variables for machine-dependent things. */
107 /* Threshold for data being put into the small data/bss area, instead
108 of the normal data area (references to the small data/bss area take
109 1 instruction, and use the global pointer, references to the normal
110 data area takes 2 instructions). */
111 int mips_section_threshold
= -1;
113 /* Count the number of .file directives, so that .loc is up to date. */
114 int num_source_filenames
= 0;
116 /* Count the number of sdb related labels are generated (to find block
117 start and end boundaries). */
118 int sdb_label_count
= 0;
120 /* Next label # for each statment for Silicon Graphics IRIS systems. */
123 /* Non-zero if inside of a function, because the stupid MIPS asm can't
124 handle .files inside of functions. */
125 int inside_function
= 0;
127 /* Files to separate the text and the data output, so that all of the data
128 can be emitted before the text, which will mean that the assembler will
129 generate smaller code, based on the global pointer. */
130 FILE *asm_out_data_file
;
131 FILE *asm_out_text_file
;
133 /* Linked list of all externals that are to be emitted when optimizing
134 for the global pointer if they haven't been declared by the end of
135 the program with an appropriate .comm or initialization. */
138 struct extern_list
*next
; /* next external */
139 char *name
; /* name of the external */
140 int size
; /* size in bytes */
143 /* Name of the file containing the current function. */
144 char *current_function_file
= "";
146 /* Warning given that Mips ECOFF can't support changing files
147 within a function. */
148 int file_in_function_warning
= FALSE
;
150 /* Whether to suppress issuing .loc's because the user attempted
151 to change the filename within a function. */
152 int ignore_line_number
= FALSE
;
154 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
160 /* The next branch instruction is a branch likely, not branch normal. */
161 int mips_branch_likely
;
163 /* Count of delay slots and how many are filled. */
164 int dslots_load_total
;
165 int dslots_load_filled
;
166 int dslots_jump_total
;
167 int dslots_jump_filled
;
169 /* # of nops needed by previous insn */
170 int dslots_number_nops
;
172 /* Number of 1/2/3 word references to data items (ie, not jal's). */
175 /* registers to check for load delay */
176 rtx mips_load_reg
, mips_load_reg2
, mips_load_reg3
, mips_load_reg4
;
178 /* Cached operands, and operator to compare for use in set/branch on
182 /* what type of branch to use */
183 enum cmp_type branch_type
;
185 /* Number of previously seen half-pic pointers and references. */
186 static int prev_half_pic_ptrs
= 0;
187 static int prev_half_pic_refs
= 0;
189 /* which cpu are we scheduling for */
190 enum processor_type mips_cpu
;
192 /* which instruction set architecture to use. */
195 /* Strings to hold which cpu and instruction set architecture to use. */
196 char *mips_cpu_string
; /* for -mcpu=<xxx> */
197 char *mips_isa_string
; /* for -mips{1,2,3} */
199 /* Generating calls to position independent functions? */
200 enum mips_abicalls_type mips_abicalls
;
202 /* High and low marks for floating point values which we will accept
203 as legitimate constants for LEGITIMATE_CONSTANT_P. These are
204 initialized in override_options. */
205 REAL_VALUE_TYPE dfhigh
, dflow
, sfhigh
, sflow
;
207 /* Array to RTX class classification. At present, we care about
208 whether the operator is an add-type operator, or a divide/modulus,
209 and if divide/modulus, whether it is unsigned. This is for the
211 char mips_rtx_classify
[NUM_RTX_CODE
];
213 /* Array giving truth value on whether or not a given hard register
214 can support a given mode. */
215 char mips_hard_regno_mode_ok
[(int)MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
217 /* Current frame information calculated by compute_frame_size. */
218 struct mips_frame_info current_frame_info
;
220 /* Zero structure to initialize current_frame_info. */
221 struct mips_frame_info zero_frame_info
;
223 /* Temporary filename used to buffer .text until end of program
225 static char *temp_filename
;
227 /* List of all MIPS punctuation characters used by print_operand. */
228 char mips_print_operand_punct
[256];
230 /* Map GCC register number to debugger register number. */
231 int mips_dbx_regno
[FIRST_PSEUDO_REGISTER
];
233 /* Buffer to use to enclose a load/store operation with %{ %} to
234 turn on .set volatile. */
235 static char volatile_buffer
[60];
237 /* Hardware names for the registers. If -mrnames is used, this
238 will be overwritten with mips_sw_reg_names. */
240 char mips_reg_names
[][8] =
242 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
243 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
244 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
245 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
246 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
247 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
248 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
249 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
253 /* Mips software names for the registers, used to overwrite the
254 mips_reg_names array. */
256 char mips_sw_reg_names
[][8] =
258 "$zero","$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3",
259 "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
260 "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7",
261 "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra",
262 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
263 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
264 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
265 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
269 /* Map hard register number to register class */
270 enum reg_class mips_regno_to_class
[] =
272 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
273 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
274 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
275 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
276 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
277 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
278 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
279 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
280 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
281 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
282 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
283 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
284 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
285 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
286 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
287 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
288 HI_REG
, LO_REG
, ST_REGS
291 /* Map register constraint character to register class. */
292 enum reg_class mips_char_to_class
[256] =
294 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
295 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
296 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
297 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
298 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
299 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
300 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
301 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
302 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
303 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
304 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
305 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
306 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
307 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
308 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
309 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
310 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
311 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
312 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
313 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
314 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
315 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
316 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
317 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
318 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
319 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
320 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
321 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
322 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
323 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
324 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
325 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
326 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
327 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
328 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
329 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
330 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
331 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
332 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
333 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
334 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
335 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
336 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
337 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
338 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
339 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
340 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
341 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
342 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
343 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
344 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
345 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
346 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
347 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
348 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
349 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
350 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
351 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
352 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
353 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
354 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
355 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
356 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
357 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
361 /* Return truth value of whether OP can be used as an operands
362 where a register or 16 bit unsigned integer is needed. */
365 uns_arith_operand (op
, mode
)
367 enum machine_mode mode
;
369 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT_UNSIGNED (op
))
372 return register_operand (op
, mode
);
375 /* Return truth value of whether OP can be used as an operands
376 where a 16 bit integer is needed */
379 arith_operand (op
, mode
)
381 enum machine_mode mode
;
383 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
))
386 return register_operand (op
, mode
);
389 /* Return truth value of whether OP can be used as an operand in a two
390 address arithmetic insn (such as set 123456,%o4) of mode MODE. */
393 arith32_operand (op
, mode
)
395 enum machine_mode mode
;
397 if (GET_CODE (op
) == CONST_INT
)
400 return register_operand (op
, mode
);
403 /* Return truth value of whether OP is a integer which fits in 16 bits */
408 enum machine_mode mode
;
410 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
413 /* Return truth value of whether OP is an integer which is too big to
414 be loaded with one instruction. */
419 enum machine_mode mode
;
423 if (GET_CODE (op
) != CONST_INT
)
427 if ((value
& ~0x0000ffff) == 0) /* ior reg,$r0,value */
430 if (((unsigned long)(value
+ 32768)) <= 32767) /* subu reg,$r0,value */
433 if ((value
& 0x0000ffff) == 0 /* lui reg,value>>16 */
434 && ((value
& ~2147483647) == 0 /* signed value */
435 || (value
& ~2147483647) == ~2147483647))
441 /* Return truth value of whether OP is a register or the constant 0. */
444 reg_or_0_operand (op
, mode
)
446 enum machine_mode mode
;
448 switch (GET_CODE (op
))
454 return (INTVAL (op
) == 0);
457 if (op
!= CONST0_RTX (mode
))
464 return register_operand (op
, mode
);
470 /* Return truth value of whether OP is one of the special multiply/divide
471 registers (hi, lo). */
474 md_register_operand (op
, mode
)
476 enum machine_mode mode
;
478 return (GET_MODE_CLASS (mode
) == MODE_INT
479 && GET_CODE (op
) == REG
480 && MD_REG_P (REGNO (op
)));
483 /* Return truth value of whether OP is the FP status register. */
486 fpsw_register_operand (op
, mode
)
488 enum machine_mode mode
;
490 return (GET_CODE (op
) == REG
&& ST_REG_P (REGNO (op
)));
493 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
496 mips_const_double_ok (op
, mode
)
498 enum machine_mode mode
;
500 if (GET_CODE (op
) != CONST_DOUBLE
)
506 if (mode
!= SFmode
&& mode
!= DFmode
)
509 if (op
== CONST0_RTX (mode
))
512 if (TARGET_MIPS_AS
) /* gas doesn't like li.d/li.s yet */
516 REAL_VALUE_FROM_CONST_DOUBLE (d
, op
);
518 if (REAL_VALUE_ISNAN (d
))
521 if (REAL_VALUE_NEGATIVE (d
))
522 d
= REAL_VALUE_NEGATE (d
);
526 if (REAL_VALUES_LESS (d
, dfhigh
)
527 && REAL_VALUES_LESS (dflow
, d
))
532 if (REAL_VALUES_LESS (d
, sfhigh
)
533 && REAL_VALUES_LESS (sflow
, d
))
541 /* Return truth value if a memory operand fits in a single instruction
542 (ie, register + small offset). */
545 simple_memory_operand (op
, mode
)
547 enum machine_mode mode
;
549 rtx addr
, plus0
, plus1
;
551 /* Eliminate non-memory operations */
552 if (GET_CODE (op
) != MEM
)
555 /* dword operations really put out 2 instructions, so eliminate them. */
556 if (GET_MODE_SIZE (GET_MODE (op
)) > UNITS_PER_WORD
)
559 /* Decode the address now. */
561 switch (GET_CODE (addr
))
570 return SMALL_INT (op
);
573 plus0
= XEXP (addr
, 0);
574 plus1
= XEXP (addr
, 1);
575 if (GET_CODE (plus0
) == REG
576 && GET_CODE (plus1
) == CONST_INT
577 && SMALL_INT (plus1
))
580 else if (GET_CODE (plus1
) == REG
581 && GET_CODE (plus0
) == CONST_INT
582 && SMALL_INT (plus0
))
589 /* We used to allow small symbol refs here (ie, stuff in .sdata
590 or .sbss), but this causes some bugs in G++. Also, it won't
591 interfere if the MIPS linker rewrites the store instruction
592 because the function is PIC. */
594 case LABEL_REF
: /* never gp relative */
598 /* If -G 0, we can never have a GP relative memory operation.
599 Also, save some time if not optimizing. */
604 rtx offset
= const0_rtx
;
605 addr
= eliminate_constant_term (XEXP (addr
, 0), &offset
);
606 if (GET_CODE (op
) != SYMBOL_REF
)
609 /* let's be paranoid.... */
610 if (! SMALL_INT (offset
))
616 return SYMBOL_REF_FLAG (addr
);
623 /* Return true if the code of this rtx pattern is EQ or NE. */
626 equality_op (op
, mode
)
628 enum machine_mode mode
;
630 if (mode
!= GET_MODE (op
))
633 return (classify_op (op
, mode
) & CLASS_EQUALITY_OP
) != 0;
636 /* Return true if the code is a relational operations (EQ, LE, etc.) */
641 enum machine_mode mode
;
643 if (mode
!= GET_MODE (op
))
646 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
650 /* Genrecog does not take the type of match_operator into consideration,
651 and would complain about two patterns being the same if the same
652 function is used, so make it believe they are different. */
657 enum machine_mode mode
;
659 if (mode
!= GET_MODE (op
))
662 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
665 /* Return true if the code is an unsigned relational operations (LEU, etc.) */
670 enum machine_mode mode
;
672 if (mode
!= GET_MODE (op
))
675 return (classify_op (op
, mode
) & CLASS_UNS_CMP_OP
) == CLASS_UNS_CMP_OP
;
678 /* Return true if the code is a relational operation FP can use. */
683 enum machine_mode mode
;
685 if (mode
!= GET_MODE (op
))
688 return (classify_op (op
, mode
) & CLASS_FCMP_OP
) != 0;
692 /* Return true if the operand is either the PC or a label_ref. */
695 pc_or_label_operand (op
, mode
)
697 enum machine_mode mode
;
702 if (GET_CODE (op
) == LABEL_REF
)
708 /* Test for a valid operand for a call instruction.
709 Don't allow the arg pointer register or virtual regs
710 since they may change into reg + const, which the patterns
714 call_insn_operand (op
, mode
)
716 enum machine_mode mode
;
718 if (GET_CODE (op
) == MEM
719 && (CONSTANT_ADDRESS_P (XEXP (op
, 0))
720 || (GET_CODE (XEXP (op
, 0)) == REG
721 && XEXP (op
, 0) != arg_pointer_rtx
722 && !(REGNO (XEXP (op
, 0)) >= FIRST_PSEUDO_REGISTER
723 && REGNO (XEXP (op
, 0)) <= LAST_VIRTUAL_REGISTER
))))
728 /* Return an operand string if the given instruction's delay slot or
729 wrap it in a .set noreorder section. This is for filling delay
730 slots on load type instructions under GAS, which does no reordering
731 on its own. For the MIPS assembler, all we do is update the filled
732 delay slot statistics.
734 We assume that operands[0] is the target register that is set.
736 In order to check the next insn, most of this functionality is moved
737 to FINAL_PRESCAN_INSN, and we just set the global variables that
741 mips_fill_delay_slot (ret
, type
, operands
, cur_insn
)
742 char *ret
; /* normal string to return */
743 enum delay_type type
; /* type of delay */
744 rtx operands
[]; /* operands to use */
745 rtx cur_insn
; /* current insn */
747 register rtx set_reg
;
748 register enum machine_mode mode
;
749 register rtx next_insn
= (cur_insn
) ? NEXT_INSN (cur_insn
) : (rtx
)0;
750 register int num_nops
;
752 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
755 else if (type
== DELAY_HILO
)
761 /* Make sure that we don't put nop's after labels. */
762 next_insn
= NEXT_INSN (cur_insn
);
763 while (next_insn
!= (rtx
)0 && GET_CODE (next_insn
) == NOTE
)
764 next_insn
= NEXT_INSN (next_insn
);
766 dslots_load_total
+= num_nops
;
767 if (TARGET_DEBUG_F_MODE
769 || type
== DELAY_NONE
770 || operands
== (rtx
*)0
771 || cur_insn
== (rtx
)0
772 || next_insn
== (rtx
)0
773 || GET_CODE (next_insn
) == CODE_LABEL
774 || (set_reg
= operands
[0]) == (rtx
)0)
776 dslots_number_nops
= 0;
777 mips_load_reg
= (rtx
)0;
778 mips_load_reg2
= (rtx
)0;
779 mips_load_reg3
= (rtx
)0;
780 mips_load_reg4
= (rtx
)0;
784 set_reg
= operands
[0];
785 if (set_reg
== (rtx
)0)
788 while (GET_CODE (set_reg
) == SUBREG
)
789 set_reg
= SUBREG_REG (set_reg
);
791 mode
= GET_MODE (set_reg
);
792 dslots_number_nops
= num_nops
;
793 mips_load_reg
= set_reg
;
794 if (GET_MODE_SIZE (mode
)
795 > (FP_REG_P (set_reg
) ? UNITS_PER_FPREG
: UNITS_PER_WORD
))
796 mips_load_reg2
= gen_rtx (REG
, SImode
, REGNO (set_reg
) + 1);
800 if (type
== DELAY_HILO
)
802 mips_load_reg3
= gen_rtx (REG
, SImode
, MD_REG_FIRST
);
803 mips_load_reg4
= gen_rtx (REG
, SImode
, MD_REG_FIRST
+1);
811 if (TARGET_GAS
&& set_noreorder
++ == 0)
812 fputs ("\t.set\tnoreorder\n", asm_out_file
);
818 /* Determine whether a memory reference takes one (based off of the GP pointer),
819 two (normal), or three (label + reg) instructions, and bump the appropriate
820 counter for -mstats. */
823 mips_count_memory_refs (op
, num
)
829 rtx addr
, plus0
, plus1
;
830 enum rtx_code code0
, code1
;
833 if (TARGET_DEBUG_B_MODE
)
835 fprintf (stderr
, "\n========== mips_count_memory_refs:\n");
839 /* Skip MEM if passed, otherwise handle movsi of address. */
840 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
842 /* Loop, going through the address RTL */
846 switch (GET_CODE (addr
))
856 plus0
= XEXP (addr
, 0);
857 plus1
= XEXP (addr
, 1);
858 code0
= GET_CODE (plus0
);
859 code1
= GET_CODE (plus1
);
869 if (code0
== CONST_INT
)
884 if (code1
== CONST_INT
)
891 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
898 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
908 n_words
= 2; /* always 2 words */
912 addr
= XEXP (addr
, 0);
917 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
926 n_words
+= additional
;
930 num_refs
[n_words
-1] += num
;
934 /* Return the appropriate instructions to move one operand to another. */
937 mips_move_1word (operands
, insn
, unsignedp
)
943 rtx op0
= operands
[0];
944 rtx op1
= operands
[1];
945 enum rtx_code code0
= GET_CODE (op0
);
946 enum rtx_code code1
= GET_CODE (op1
);
947 enum machine_mode mode
= GET_MODE (op0
);
948 int subreg_word0
= 0;
949 int subreg_word1
= 0;
950 enum delay_type delay
= DELAY_NONE
;
952 while (code0
== SUBREG
)
954 subreg_word0
+= SUBREG_WORD (op0
);
955 op0
= SUBREG_REG (op0
);
956 code0
= GET_CODE (op0
);
959 while (code1
== SUBREG
)
961 subreg_word1
+= SUBREG_WORD (op1
);
962 op1
= SUBREG_REG (op1
);
963 code1
= GET_CODE (op1
);
968 int regno0
= REGNO (op0
) + subreg_word0
;
972 int regno1
= REGNO (op1
) + subreg_word1
;
974 /* Just in case, don't do anything for assigning a register
975 to itself, unless we are filling a delay slot. */
976 if (regno0
== regno1
&& set_nomacro
== 0)
979 else if (GP_REG_P (regno0
))
981 if (GP_REG_P (regno1
))
984 else if (MD_REG_P (regno1
))
993 if (FP_REG_P (regno1
))
996 else if (regno1
== FPSW_REGNUM
)
997 ret
= "cfc1\t%0,$31";
1001 else if (FP_REG_P (regno0
))
1003 if (GP_REG_P (regno1
))
1006 ret
= "mtc1\t%1,%0";
1009 if (FP_REG_P (regno1
))
1010 ret
= "mov.s\t%0,%1";
1013 else if (MD_REG_P (regno0
))
1015 if (GP_REG_P (regno1
))
1022 else if (regno0
== FPSW_REGNUM
)
1024 if (GP_REG_P (regno1
))
1027 ret
= "ctc1\t%0,$31";
1032 else if (code1
== MEM
)
1037 mips_count_memory_refs (op1
, 1);
1039 if (GP_REG_P (regno0
))
1041 /* For loads, use the mode of the memory item, instead of the
1042 target, so zero/sign extend can use this code as well. */
1043 switch (GET_MODE (op1
))
1051 ret
= ((unsignedp
&& TARGET_64BIT
)
1056 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
1059 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
1064 else if (FP_REG_P (regno0
) && (mode
== SImode
|| mode
== SFmode
))
1067 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1069 int i
= strlen (ret
);
1070 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1073 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1074 ret
= volatile_buffer
;
1078 else if (code1
== CONST_INT
)
1080 if (INTVAL (op1
) == 0)
1082 if (GP_REG_P (regno0
))
1083 ret
= "move\t%0,%z1";
1085 else if (FP_REG_P (regno0
))
1088 ret
= "mtc1\t%z1,%0";
1092 else if (GP_REG_P (regno0
))
1093 ret
= (INTVAL (op1
) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1";
1096 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
1098 if (op1
== CONST0_RTX (SFmode
))
1100 if (GP_REG_P (regno0
))
1101 ret
= "move\t%0,%.";
1103 else if (FP_REG_P (regno0
))
1106 ret
= "mtc1\t%.,%0";
1113 ret
= "li.s\t%0,%1";
1117 else if (code1
== LABEL_REF
)
1120 mips_count_memory_refs (op1
, 1);
1125 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
1127 if (HALF_PIC_P () && CONSTANT_P (op1
) && HALF_PIC_ADDRESS_P (op1
))
1129 rtx offset
= const0_rtx
;
1131 if (GET_CODE (op1
) == CONST
)
1132 op1
= eliminate_constant_term (XEXP (op1
, 0), &offset
);
1134 if (GET_CODE (op1
) == SYMBOL_REF
)
1136 operands
[2] = HALF_PIC_PTR (op1
);
1139 mips_count_memory_refs (operands
[2], 1);
1141 if (INTVAL (offset
) == 0)
1144 ret
= (unsignedp
&& TARGET_64BIT
1150 dslots_load_total
++;
1151 operands
[3] = offset
;
1152 if (unsignedp
&& TARGET_64BIT
)
1153 ret
= (SMALL_INT (offset
))
1154 ? "lwu\t%0,%2%#\n\tadd\t%0,%0,%3"
1155 : "lwu\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1157 ret
= (SMALL_INT (offset
))
1158 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"
1159 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1166 mips_count_memory_refs (op1
, 1);
1172 else if (code1
== PLUS
)
1174 rtx add_op0
= XEXP (op1
, 0);
1175 rtx add_op1
= XEXP (op1
, 1);
1177 if (GET_CODE (XEXP (op1
, 1)) == REG
&& GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
1179 add_op0
= XEXP (op1
, 1); /* reverse operands */
1180 add_op1
= XEXP (op1
, 0);
1183 operands
[2] = add_op0
;
1184 operands
[3] = add_op1
;
1185 ret
= "add%:\t%0,%2,%3";
1189 else if (code0
== MEM
)
1192 mips_count_memory_refs (op0
, 1);
1196 int regno1
= REGNO (op1
) + subreg_word1
;
1198 if (GP_REG_P (regno1
))
1203 case SFmode
: ret
= "sw\t%1,%0"; break;
1204 case SImode
: ret
= "sw\t%1,%0"; break;
1205 case HImode
: ret
= "sh\t%1,%0"; break;
1206 case QImode
: ret
= "sb\t%1,%0"; break;
1210 else if (FP_REG_P (regno1
) && (mode
== SImode
|| mode
== SFmode
))
1214 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1219 case SFmode
: ret
= "sw\t%z1,%0"; break;
1220 case SImode
: ret
= "sw\t%z1,%0"; break;
1221 case HImode
: ret
= "sh\t%z1,%0"; break;
1222 case QImode
: ret
= "sb\t%z1,%0"; break;
1226 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
1231 case SFmode
: ret
= "sw\t%.,%0"; break;
1232 case SImode
: ret
= "sw\t%.,%0"; break;
1233 case HImode
: ret
= "sh\t%.,%0"; break;
1234 case QImode
: ret
= "sb\t%.,%0"; break;
1238 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1240 int i
= strlen (ret
);
1241 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1244 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1245 ret
= volatile_buffer
;
1249 if (ret
== (char *)0)
1251 abort_with_insn (insn
, "Bad move");
1255 if (delay
!= DELAY_NONE
)
1256 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1262 /* Return the appropriate instructions to move 2 words */
1265 mips_move_2words (operands
, insn
)
1270 rtx op0
= operands
[0];
1271 rtx op1
= operands
[1];
1272 enum rtx_code code0
= GET_CODE (operands
[0]);
1273 enum rtx_code code1
= GET_CODE (operands
[1]);
1274 int subreg_word0
= 0;
1275 int subreg_word1
= 0;
1276 enum delay_type delay
= DELAY_NONE
;
1278 while (code0
== SUBREG
)
1280 subreg_word0
+= SUBREG_WORD (op0
);
1281 op0
= SUBREG_REG (op0
);
1282 code0
= GET_CODE (op0
);
1285 while (code1
== SUBREG
)
1287 subreg_word1
+= SUBREG_WORD (op1
);
1288 op1
= SUBREG_REG (op1
);
1289 code1
= GET_CODE (op1
);
1294 int regno0
= REGNO (op0
) + subreg_word0
;
1298 int regno1
= REGNO (op1
) + subreg_word1
;
1300 /* Just in case, don't do anything for assigning a register
1301 to itself, unless we are filling a delay slot. */
1302 if (regno0
== regno1
&& set_nomacro
== 0)
1305 else if (FP_REG_P (regno0
))
1307 if (FP_REG_P (regno1
))
1308 ret
= "mov.d\t%0,%1";
1316 abort_with_insn (insn
, "Bad move");
1317 #ifdef TARGET_FP_CALL_32
1318 if (FP_CALL_GP_REG_P (regno1
))
1319 ret
= "dsll\t%1,32\n\tor\t%1,%D1\n\tdmtc1\t%1,%0";
1322 ret
= "dmtc1\t%1,%0";
1325 ret
= "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";
1329 else if (FP_REG_P (regno1
))
1335 abort_with_insn (insn
, "Bad move");
1336 #ifdef TARGET_FP_CALL_32
1337 if (FP_CALL_GP_REG_P (regno0
))
1338 ret
= "dmfc1\t%0,%1\n\tmfc1\t%D0,%1\n\tdsrl\t%0,32";
1341 ret
= "dmfc1\t%0,%1";
1344 ret
= "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";
1347 else if (MD_REG_P (regno0
) && GP_REG_P (regno1
))
1353 ret
= "mthi\t%M1\n\tmtlo\t%L1";
1356 else if (GP_REG_P (regno0
) && MD_REG_P (regno1
))
1362 ret
= "mfhi\t%M0\n\tmflo\t%L0";
1365 else if (TARGET_64BIT
)
1366 ret
= "move\t%0,%1";
1368 else if (regno0
!= (regno1
+1))
1369 ret
= "move\t%0,%1\n\tmove\t%D0,%D1";
1372 ret
= "move\t%D0,%D1\n\tmove\t%0,%1";
1375 else if (code1
== CONST_DOUBLE
)
1377 /* Move zero from $0 unless !TARGET_64BIT and recipient
1378 is 64-bit fp reg, in which case generate a constant. */
1379 if (op1
!= CONST0_RTX (GET_MODE (op1
))
1380 || (TARGET_FLOAT64
&& !TARGET_64BIT
&& FP_REG_P (regno0
)))
1382 if (GET_MODE (op1
) == DFmode
)
1385 #ifdef TARGET_FP_CALL_32
1386 if (FP_CALL_GP_REG_P (regno0
))
1388 if (TARGET_FLOAT64
&& !TARGET_64BIT
)
1390 operands
[2] = GEN_INT (CONST_DOUBLE_LOW (op1
));
1391 operands
[3] = GEN_INT (CONST_DOUBLE_HIGH (op1
));
1392 ret
= "li\t%M0,%3\n\tli\t%L0,%2";
1395 ret
= "li.d\t%0,%1\n\tdsll\t%D0,%0,32\n\tdsrl\t%D0,32\n\tdsrl\t%0,32";
1399 ret
= "li.d\t%0,%1";
1402 else if (TARGET_FLOAT64
)
1407 operands
[2] = GEN_INT (CONST_DOUBLE_LOW (op1
));
1408 operands
[3] = GEN_INT (CONST_DOUBLE_HIGH (op1
));
1409 ret
= "li\t%M0,%3\n\tli\t%L0,%2";
1415 if (GP_REG_P (regno0
))
1417 #ifdef TARGET_FP_CALL_32
1418 && ! FP_CALL_GP_REG_P (regno0
)
1422 : "move\t%0,%.\n\tmove\t%D0,%.";
1424 else if (FP_REG_P (regno0
))
1427 ret
= (TARGET_64BIT
)
1429 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1434 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1436 if (GP_REG_P (regno0
))
1437 ret
= (TARGET_64BIT
)
1439 : "move\t%0,%.\n\tmove\t%D0,%.";
1441 else if (FP_REG_P (regno0
))
1444 ret
= (TARGET_64BIT
)
1448 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0");
1452 else if (code1
== CONST_INT
&& GET_MODE (op0
) == DImode
&& GP_REG_P (regno0
))
1458 operands
[2] = GEN_INT (INTVAL (operands
[1]) >= 0 ? 0 : -1);
1459 ret
= "li\t%M0,%2\n\tli\t%L0,%1";
1463 else if (code1
== MEM
)
1468 mips_count_memory_refs (op1
, 2);
1470 if (FP_REG_P (regno0
))
1473 else if (TARGET_64BIT
)
1475 #ifdef TARGET_FP_CALL_32
1476 if (FP_CALL_GP_REG_P (regno0
))
1478 if (offsettable_address_p (FALSE
, SImode
, op1
))
1479 ret
= "lwu\t%0,%1\n\tlwu\t%D0,4+%1";
1481 ret
= "ld\t%0,%1\n\tdsll\t%D0,%0,32\n\tdsrl\t%D0,32\n\tdsrl\t%0,32";
1488 else if (offsettable_address_p (1, DFmode
, XEXP (op1
, 0)))
1490 operands
[2] = adj_offsettable_operand (op1
, 4);
1491 if (reg_mentioned_p (op0
, op1
))
1492 ret
= "lw\t%D0,%2\n\tlw\t%0,%1";
1494 ret
= "lw\t%0,%1\n\tlw\t%D0,%2";
1497 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1499 int i
= strlen (ret
);
1500 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1503 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1504 ret
= volatile_buffer
;
1508 else if (code1
== LABEL_REF
1509 || code1
== SYMBOL_REF
1514 return mips_move_1word (operands
, insn
, 0);
1518 else if (code0
== MEM
)
1522 int regno1
= REGNO (op1
) + subreg_word1
;
1524 if (FP_REG_P (regno1
))
1527 else if (TARGET_64BIT
)
1529 #ifdef TARGET_FP_CALL_32
1530 if (FP_CALL_GP_REG_P (regno1
))
1531 ret
= "dsll\t%1,32\n\tor\t%1,%D1\n\tsd\t%1,%0";
1537 else if (offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1539 operands
[2] = adj_offsettable_operand (op0
, 4);
1540 ret
= "sw\t%1,%0\n\tsw\t%D1,%2";
1544 else if (((code1
== CONST_INT
&& INTVAL (op1
) == 0)
1545 || (code1
== CONST_DOUBLE
1546 && op1
== CONST0_RTX (GET_MODE (op1
))))
1548 || offsettable_address_p (1, DFmode
, XEXP (op0
, 0))))
1554 operands
[2] = adj_offsettable_operand (op0
, 4);
1555 ret
= "sw\t%.,%0\n\tsw\t%.,%2";
1560 mips_count_memory_refs (op0
, 2);
1562 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1564 int i
= strlen (ret
);
1565 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1568 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1569 ret
= volatile_buffer
;
1573 if (ret
== (char *)0)
1575 abort_with_insn (insn
, "Bad move");
1579 if (delay
!= DELAY_NONE
)
1580 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1586 /* Provide the costs of an addressing mode that contains ADDR.
1587 If ADDR is not a valid address, its cost is irrelevant. */
1590 mips_address_cost (addr
)
1593 switch (GET_CODE (addr
))
1607 rtx offset
= const0_rtx
;
1608 addr
= eliminate_constant_term (XEXP (addr
, 0), &offset
);
1609 if (GET_CODE (addr
) == LABEL_REF
)
1612 if (GET_CODE (addr
) != SYMBOL_REF
)
1615 if (! SMALL_INT (offset
))
1621 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
1625 register rtx plus0
= XEXP (addr
, 0);
1626 register rtx plus1
= XEXP (addr
, 1);
1628 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1630 plus0
= XEXP (addr
, 1);
1631 plus1
= XEXP (addr
, 0);
1634 if (GET_CODE (plus0
) != REG
)
1637 switch (GET_CODE (plus1
))
1643 return (SMALL_INT (plus1
) ? 1 : 2);
1650 return mips_address_cost (plus1
) + 1;
1658 /* Return true if X is an address which needs a temporary register when
1659 reloaded while generating PIC code. */
1662 pic_address_needs_scratch (x
)
1665 /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
1666 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
1667 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
1668 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
1669 && ! SMALL_INT (XEXP (XEXP (x
, 0), 1)))
1675 /* Make normal rtx_code into something we can index from an array */
1677 static enum internal_test
1678 map_test_to_internal_test (test_code
)
1679 enum rtx_code test_code
;
1681 enum internal_test test
= ITEST_MAX
;
1686 case EQ
: test
= ITEST_EQ
; break;
1687 case NE
: test
= ITEST_NE
; break;
1688 case GT
: test
= ITEST_GT
; break;
1689 case GE
: test
= ITEST_GE
; break;
1690 case LT
: test
= ITEST_LT
; break;
1691 case LE
: test
= ITEST_LE
; break;
1692 case GTU
: test
= ITEST_GTU
; break;
1693 case GEU
: test
= ITEST_GEU
; break;
1694 case LTU
: test
= ITEST_LTU
; break;
1695 case LEU
: test
= ITEST_LEU
; break;
1702 /* Generate the code to compare two integer values. The return value is:
1703 (reg:SI xx) The pseudo register the comparison is in
1704 (rtx)0 No register, generate a simple branch.
1706 ??? This is called with result nonzero by the Scond patterns in
1707 mips.md. These patterns are called with a target in the mode of
1708 the Scond instruction pattern. Since this must be a constant, we
1709 must use SImode. This means that if RESULT is non-zero, it will
1710 always be an SImode register, even if TARGET_64BIT is true. We
1711 cope with this by calling convert_move rather than emit_move_insn.
1712 This will sometimes lead to an unnecessary extension of the result;
1724 gen_int_relational (test_code
, result
, cmp0
, cmp1
, p_invert
)
1725 enum rtx_code test_code
; /* relational test (EQ, etc) */
1726 rtx result
; /* result to store comp. or 0 if branch */
1727 rtx cmp0
; /* first operand to compare */
1728 rtx cmp1
; /* second operand to compare */
1729 int *p_invert
; /* NULL or ptr to hold whether branch needs */
1730 /* to reverse its test */
1733 enum rtx_code test_code
; /* code to use in instruction (LT vs. LTU) */
1734 int const_low
; /* low bound of constant we can accept */
1735 int const_high
; /* high bound of constant we can accept */
1736 int const_add
; /* constant to add (convert LE -> LT) */
1737 int reverse_regs
; /* reverse registers in test */
1738 int invert_const
; /* != 0 if invert value if cmp1 is constant */
1739 int invert_reg
; /* != 0 if invert value if cmp1 is register */
1740 int unsignedp
; /* != 0 for unsigned comparisons. */
1743 static struct cmp_info info
[ (int)ITEST_MAX
] = {
1745 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1746 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1747 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1748 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1749 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1750 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1751 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1752 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1753 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1754 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1757 enum internal_test test
;
1758 enum machine_mode mode
;
1759 struct cmp_info
*p_info
;
1766 test
= map_test_to_internal_test (test_code
);
1767 if (test
== ITEST_MAX
)
1770 p_info
= &info
[ (int)test
];
1771 eqne_p
= (p_info
->test_code
== XOR
);
1773 mode
= GET_MODE (cmp0
);
1774 if (mode
== VOIDmode
)
1775 mode
= GET_MODE (cmp1
);
1777 /* Eliminate simple branches */
1778 branch_p
= (result
== (rtx
)0);
1781 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
1783 /* Comparisons against zero are simple branches */
1784 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1787 /* Test for beq/bne. */
1792 /* allocate a pseudo to calculate the value in. */
1793 result
= gen_reg_rtx (mode
);
1796 /* Make sure we can handle any constants given to us. */
1797 if (GET_CODE (cmp0
) == CONST_INT
)
1798 cmp0
= force_reg (mode
, cmp0
);
1800 if (GET_CODE (cmp1
) == CONST_INT
)
1802 HOST_WIDE_INT value
= INTVAL (cmp1
);
1803 if (value
< p_info
->const_low
1804 || value
> p_info
->const_high
1805 /* ??? Why? And why wasn't the similar code below modified too? */
1807 && HOST_BITS_PER_WIDE_INT
< 64
1808 && p_info
->const_add
!= 0
1809 && ((p_info
->unsignedp
1810 ? ((unsigned HOST_WIDE_INT
) (value
+ p_info
->const_add
)
1812 : (value
+ p_info
->const_add
) > INTVAL (cmp1
))
1813 != (p_info
->const_add
> 0))))
1814 cmp1
= force_reg (mode
, cmp1
);
1817 /* See if we need to invert the result. */
1818 invert
= (GET_CODE (cmp1
) == CONST_INT
)
1819 ? p_info
->invert_const
1820 : p_info
->invert_reg
;
1822 if (p_invert
!= (int *)0)
1828 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1829 Comparison between two registers, may involve switching operands. */
1830 if (GET_CODE (cmp1
) == CONST_INT
)
1832 if (p_info
->const_add
!= 0)
1834 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
1835 /* If modification of cmp1 caused overflow,
1836 we would get the wrong answer if we follow the usual path;
1837 thus, x > 0xffffffffu would turn into x > 0u. */
1838 if ((p_info
->unsignedp
1839 ? (unsigned HOST_WIDE_INT
) new > INTVAL (cmp1
)
1840 : new > INTVAL (cmp1
))
1841 != (p_info
->const_add
> 0))
1843 /* This test is always true, but if INVERT is true then
1844 the result of the test needs to be inverted so 0 should
1845 be returned instead. */
1846 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1850 cmp1
= GEN_INT (new);
1853 else if (p_info
->reverse_regs
)
1860 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1864 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
1865 convert_move (reg
, gen_rtx (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
1868 if (test
== ITEST_NE
)
1870 convert_move (result
, gen_rtx (GTU
, mode
, reg
, const0_rtx
), 0);
1874 else if (test
== ITEST_EQ
)
1876 reg2
= (invert
) ? gen_reg_rtx (mode
) : result
;
1877 convert_move (reg2
, gen_rtx (LTU
, mode
, reg
, const1_rtx
), 0);
1882 convert_move (result
, gen_rtx (XOR
, mode
, reg
, const1_rtx
), 0);
1888 /* Emit the common code for doing conditional branches.
1889 operand[0] is the label to jump to.
1890 The comparison operands are saved away by cmp{si,di,sf,df}. */
1893 gen_conditional_branch (operands
, test_code
)
1895 enum rtx_code test_code
;
1897 static enum machine_mode mode_map
[(int)CMP_MAX
][(int)ITEST_MAX
] = {
1924 CC_REV_FPmode
, /* ne */
1936 CC_REV_FPmode
, /* ne */
1948 enum machine_mode mode
;
1949 enum cmp_type type
= branch_type
;
1950 rtx cmp0
= branch_cmp
[0];
1951 rtx cmp1
= branch_cmp
[1];
1952 rtx label1
= gen_rtx (LABEL_REF
, VOIDmode
, operands
[0]);
1953 rtx label2
= pc_rtx
;
1956 enum internal_test test
= map_test_to_internal_test (test_code
);
1958 if (test
== ITEST_MAX
)
1964 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
1965 mode
= mode_map
[(int)type
][(int)test
];
1966 if (mode
== VOIDmode
)
1976 reg
= gen_int_relational (test_code
, (rtx
)0, cmp0
, cmp1
, &invert
);
1984 /* Make sure not non-zero constant if ==/!= */
1985 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1986 cmp1
= force_reg (mode
, cmp1
);
1993 rtx reg
= gen_rtx (REG
, mode
, FPSW_REGNUM
);
1994 emit_insn (gen_rtx (SET
, VOIDmode
, reg
, gen_rtx (test_code
, mode
, cmp0
, cmp1
)));
2002 /* Generate the jump */
2009 emit_jump_insn (gen_rtx (SET
, VOIDmode
,
2011 gen_rtx (IF_THEN_ELSE
, VOIDmode
,
2012 gen_rtx (test_code
, mode
, cmp0
, cmp1
),
2019 abort_with_insn (gen_rtx (test_code
, mode
, cmp0
, cmp1
), "bad test");
2024 /* Internal code to generate the load and store of one word/short/byte.
2025 The load is emitted directly, and the store insn is returned. */
2027 #define UNITS_PER_MIPS_DWORD 8
2028 #define UNITS_PER_MIPS_WORD 4
2029 #define UNITS_PER_MIPS_HWORD 2
2032 block_move_load_store (dest_reg
, src_reg
, p_bytes
, p_offset
, align
, orig_src
)
2033 rtx src_reg
; /* register holding source memory address */
2034 rtx dest_reg
; /* register holding dest. memory address */
2035 int *p_bytes
; /* pointer to # bytes remaining */
2036 int *p_offset
; /* pointer to current offset */
2037 int align
; /* alignment */
2038 rtx orig_src
; /* original source for making a reg note */
2040 int bytes
; /* # bytes remaining */
2041 int offset
; /* offset to use */
2042 int size
; /* size in bytes of load/store */
2043 enum machine_mode mode
; /* mode to use for load/store */
2044 rtx reg
; /* temporary register */
2045 rtx src_addr
; /* source address */
2046 rtx dest_addr
; /* destination address */
2047 rtx insn
; /* insn of the load */
2048 rtx orig_src_addr
; /* original source address */
2049 rtx (*load_func
)(); /* function to generate load insn */
2050 rtx (*store_func
)(); /* function to generate destination insn */
2053 if (bytes
<= 0 || align
<= 0)
2056 if (bytes
>= UNITS_PER_MIPS_DWORD
&& align
>= UNIS_PER_MIPS_DWORD
)
2059 size
= UNITS_PER_MIPS_DWORD
;
2060 load_func
= gen_movdi
;
2061 store_func
= gen_movdi
;
2063 else if (bytes
>= UNITS_PER_MIPS_WORD
&& align
>= UNITS_PER_MIPS_WORD
)
2066 size
= UNITS_PER_MIPS_WORD
;
2067 load_func
= gen_movsi
;
2068 store_func
= gen_movsi
;
2072 /* Don't generate unaligned moves here, rather defer those to the
2073 general movestrsi_internal pattern.
2074 If this gets commented back in, then should add the dword equivalent. */
2075 else if (bytes
>= UNITS_PER_MIPS_WORD
)
2078 size
= UNITS_PER_MIPS_WORD
;
2079 load_func
= gen_movsi_ulw
;
2080 store_func
= gen_movsi_usw
;
2084 else if (bytes
>= UNITS_PER_MIPS_SHORT
&& align
>= UNITS_PER_MIPS_SHORT
)
2087 size
= UNITS_PER_MIPS_SHORT
;
2088 load_func
= gen_movhi
;
2089 store_func
= gen_movhi
;
2096 load_func
= gen_movqi
;
2097 store_func
= gen_movqi
;
2101 *p_offset
= offset
+ size
;
2102 *p_bytes
= bytes
- size
;
2107 dest_addr
= dest_reg
;
2111 src_addr
= gen_rtx (PLUS
, Pmode
, src_reg
, GEN_INT (offset
));
2112 dest_addr
= gen_rtx (PLUS
, Pmode
, dest_reg
, GEN_INT (offset
));
2115 reg
= gen_reg_rtx (mode
);
2116 insn
= emit_insn ((*load_func
) (reg
, gen_rtx (MEM
, mode
, src_addr
)));
2117 orig_src_addr
= XEXP (orig_src
, 0);
2118 if (CONSTANT_P (orig_src_addr
))
2119 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUIV
,
2120 plus_constant (orig_src_addr
, offset
),
2123 return (*store_func
) (gen_rtx (MEM
, mode
, dest_addr
), reg
);
2128 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows:
2140 This way, no NOP's are needed, except at the end, and only
2141 two temp registers are needed. Two delay slots are used
2142 in deference to the R4000. */
2146 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
)
2147 rtx dest_reg
; /* register holding destination address */
2148 rtx src_reg
; /* register holding source address */
2149 int bytes
; /* # bytes to move */
2150 int align
; /* max alignment to assume */
2151 rtx orig_src
; /* original source for making a reg note */
2154 rtx prev2_store
= (rtx
)0;
2155 rtx prev_store
= (rtx
)0;
2156 rtx cur_store
= (rtx
)0;
2160 /* Is there a store to do? */
2162 emit_insn (prev2_store
);
2164 prev2_store
= prev_store
;
2165 prev_store
= cur_store
;
2166 cur_store
= block_move_load_store (dest_reg
, src_reg
,
2171 /* Finish up last three stores. */
2173 emit_insn (prev2_store
);
2176 emit_insn (prev_store
);
2179 emit_insn (cur_store
);
2184 /* Write a loop to move a constant number of bytes. Generate load/stores as follows:
2190 temp<last> = src[MAX_MOVE_REGS-1];
2194 dest[MAX_MOVE_REGS-1] = temp<last>;
2195 src += MAX_MOVE_REGS;
2196 dest += MAX_MOVE_REGS;
2197 } while (src != final);
2199 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp
2200 registers are needed.
2202 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3
2203 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every
2204 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */
2206 #define MAX_MOVE_REGS 4
2207 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2209 /* ??? Should add code to use DWORD load/stores. */
2212 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
)
2213 rtx dest_reg
; /* register holding destination address */
2214 rtx src_reg
; /* register holding source address */
2215 int bytes
; /* # bytes to move */
2216 int align
; /* alignment */
2217 rtx orig_src
; /* original source for making a reg note */
2219 rtx dest_mem
= gen_rtx (MEM
, BLKmode
, dest_reg
);
2220 rtx src_mem
= gen_rtx (MEM
, BLKmode
, src_reg
);
2221 rtx align_rtx
= GEN_INT (align
);
2227 if (bytes
< 2*MAX_MOVE_BYTES
)
2230 leftover
= bytes
% MAX_MOVE_BYTES
;
2233 label
= gen_label_rtx ();
2234 final_src
= gen_reg_rtx (Pmode
);
2235 bytes_rtx
= GEN_INT (bytes
);
2241 emit_insn (gen_movdi (final_src
, bytes_rtx
));
2242 emit_insn (gen_adddi3 (final_src
, final_src
, src_reg
));
2246 emit_insn (gen_movsi (final_src
, bytes_rtx
));
2247 emit_insn (gen_addsi3 (final_src
, final_src
, src_reg
));
2253 emit_insn (gen_adddi3 (final_src
, src_reg
, bytes_rtx
));
2255 emit_insn (gen_addsi3 (final_src
, src_reg
, bytes_rtx
));
2260 bytes_rtx
= GEN_INT (MAX_MOVE_BYTES
);
2261 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
, bytes_rtx
, align_rtx
));
2264 emit_insn (gen_adddi3 (src_reg
, src_reg
, bytes_rtx
));
2265 emit_insn (gen_adddi3 (dest_reg
, dest_reg
, bytes_rtx
));
2266 emit_insn (gen_cmpdi (src_reg
, final_src
));
2270 emit_insn (gen_addsi3 (src_reg
, src_reg
, bytes_rtx
));
2271 emit_insn (gen_addsi3 (dest_reg
, dest_reg
, bytes_rtx
));
2272 emit_insn (gen_cmpsi (src_reg
, final_src
));
2274 emit_jump_insn (gen_bne (label
));
2277 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
,
2283 /* Use a library function to move some bytes. */
2286 block_move_call (dest_reg
, src_reg
, bytes_rtx
)
2291 /* We want to pass the size as Pmode, which will normally be SImode
2292 but will be DImode if we are using 64 bit longs and pointers. */
2293 if (GET_MODE (bytes_rtx
) != VOIDmode
2294 && GET_MODE (bytes_rtx
) != Pmode
)
2295 bytes_rtx
= convert_to_mode (Pmode
, bytes_rtx
, TRUE
);
2297 #ifdef TARGET_MEM_FUNCTIONS
2298 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "memcpy"), 0,
2304 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "bcopy"), 0,
2313 /* Expand string/block move operations.
2315 operands[0] is the pointer to the destination.
2316 operands[1] is the pointer to the source.
2317 operands[2] is the number of bytes to move.
2318 operands[3] is the alignment. */
2321 expand_block_move (operands
)
2324 rtx bytes_rtx
= operands
[2];
2325 rtx align_rtx
= operands
[3];
2326 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2327 int bytes
= (constp
? INTVAL (bytes_rtx
) : 0);
2328 int align
= INTVAL (align_rtx
);
2329 rtx orig_src
= operands
[1];
2333 if (constp
&& bytes
<= 0)
2336 if (align
> UNITS_PER_WORD
)
2337 align
= UNITS_PER_WORD
;
2339 /* Move the address into scratch registers. */
2340 dest_reg
= copy_addr_to_reg (XEXP (operands
[0], 0));
2341 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2344 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2347 else if (constp
&& bytes
<= 3*align
)
2348 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2351 else if (constp
&& bytes
<= 2*MAX_MOVE_BYTES
)
2352 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2353 gen_rtx (MEM
, BLKmode
, src_reg
),
2354 bytes_rtx
, align_rtx
));
2356 else if (constp
&& align
>= UNITS_PER_WORD
&& optimize
)
2357 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2359 else if (constp
&& optimize
)
2361 /* If the alignment is not word aligned, generate a test at
2362 runtime, to see whether things wound up aligned, and we
2363 can use the faster lw/sw instead ulw/usw. */
2365 rtx temp
= gen_reg_rtx (Pmode
);
2366 rtx aligned_label
= gen_label_rtx ();
2367 rtx join_label
= gen_label_rtx ();
2368 int leftover
= bytes
% MAX_MOVE_BYTES
;
2374 emit_insn (gen_iordi3 (temp
, src_reg
, dest_reg
));
2375 emit_insn (gen_anddi3 (temp
, temp
, GEN_INT (UNITS_PER_WORD
-1)));
2376 emit_insn (gen_cmpdi (temp
, const0_rtx
));
2380 emit_insn (gen_iorsi3 (temp
, src_reg
, dest_reg
));
2381 emit_insn (gen_andsi3 (temp
, temp
, GEN_INT (UNITS_PER_WORD
-1)));
2382 emit_insn (gen_cmpsi (temp
, const0_rtx
));
2384 emit_jump_insn (gen_beq (aligned_label
));
2386 /* Unaligned loop. */
2387 block_move_loop (dest_reg
, src_reg
, bytes
, 1, orig_src
);
2388 emit_jump_insn (gen_jump (join_label
));
2392 emit_label (aligned_label
);
2393 block_move_loop (dest_reg
, src_reg
, bytes
, UNITS_PER_WORD
, orig_src
);
2394 emit_label (join_label
);
2396 /* Bytes at the end of the loop. */
2400 if (leftover
<= 3*align
)
2401 block_move_sequence (dest_reg
, src_reg
, leftover
, align
, orig_src
);
2405 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2406 gen_rtx (MEM
, BLKmode
, src_reg
),
2413 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2417 /* Emit load/stores for a small constant block_move.
2419 operands[0] is the memory address of the destination.
2420 operands[1] is the memory address of the source.
2421 operands[2] is the number of bytes to move.
2422 operands[3] is the alignment.
2423 operands[4] is a temp register.
2424 operands[5] is a temp register.
2426 operands[3+num_regs] is the last temp register.
2428 The block move type can be one of the following:
2429 BLOCK_MOVE_NORMAL Do all of the block move.
2430 BLOCK_MOVE_NOT_LAST Do all but the last store.
2431 BLOCK_MOVE_LAST Do just the last store. */
2434 output_block_move (insn
, operands
, num_regs
, move_type
)
2438 enum block_move_type move_type
;
2440 rtx dest_reg
= XEXP (operands
[0], 0);
2441 rtx src_reg
= XEXP (operands
[1], 0);
2442 int bytes
= INTVAL (operands
[2]);
2443 int align
= INTVAL (operands
[3]);
2446 int use_lwl_lwr
= FALSE
;
2447 int last_operand
= num_regs
+4;
2453 char *load
; /* load insn without nop */
2454 char *load_nop
; /* load insn with trailing nop */
2455 char *store
; /* store insn */
2456 char *final
; /* if last_store used: NULL or swr */
2457 char *last_store
; /* last store instruction */
2458 int offset
; /* current offset */
2459 enum machine_mode mode
; /* mode to use on (MEM) */
2462 /* Detect a bug in GCC, where it can give us a register
2463 the same as one of the addressing registers and reduce
2464 the number of registers available. */
2466 i
< last_operand
&& safe_regs
< (sizeof(xoperands
) / sizeof(xoperands
[0]));
2469 if (!reg_mentioned_p (operands
[i
], operands
[0])
2470 && !reg_mentioned_p (operands
[i
], operands
[1]))
2472 xoperands
[safe_regs
++] = operands
[i
];
2475 if (safe_regs
< last_operand
)
2477 xoperands
[0] = operands
[0];
2478 xoperands
[1] = operands
[1];
2479 xoperands
[2] = operands
[2];
2480 xoperands
[3] = operands
[3];
2481 return output_block_move (insn
, xoperands
, safe_regs
-4, move_type
);
2484 /* If we are given global or static addresses, and we would be
2485 emitting a few instructions, try to save time by using a
2486 temporary register for the pointer. */
2487 if (num_regs
> 2 && (bytes
> 2*align
|| move_type
!= BLOCK_MOVE_NORMAL
))
2489 if (CONSTANT_P (src_reg
))
2492 mips_count_memory_refs (operands
[1], 1);
2494 src_reg
= operands
[ 3 + num_regs
-- ];
2495 if (move_type
!= BLOCK_MOVE_LAST
)
2497 xoperands
[1] = operands
[1];
2498 xoperands
[0] = src_reg
;
2499 output_asm_insn ("la\t%0,%1", xoperands
);
2503 if (CONSTANT_P (dest_reg
))
2506 mips_count_memory_refs (operands
[0], 1);
2508 dest_reg
= operands
[ 3 + num_regs
-- ];
2509 if (move_type
!= BLOCK_MOVE_LAST
)
2511 xoperands
[1] = operands
[0];
2512 xoperands
[0] = dest_reg
;
2513 output_asm_insn ("la\t%0,%1", xoperands
);
2518 if (num_regs
> (sizeof (load_store
) / sizeof (load_store
[0])))
2519 num_regs
= (sizeof (load_store
) / sizeof (load_store
[0]));
2521 else if (num_regs
< 1)
2522 abort_with_insn (insn
, "Cannot do block move, not enough scratch registers");
2524 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& set_noreorder
++ == 0)
2525 output_asm_insn (".set\tnoreorder", operands
);
2529 load_store
[num
].offset
= offset
;
2531 if (TARGET_64BIT
&& bytes
>= 8 && align
>= 8)
2533 load_store
[num
].load
= "ld\t%0,%1";
2534 load_store
[num
].load_nop
= "ld\t%0,%1%#";
2535 load_store
[num
].store
= "sd\t%0,%1";
2536 load_store
[num
].last_store
= "sd\t%0,%1";
2537 load_store
[num
].final
= (char *)0;
2538 load_store
[num
].mode
= DImode
;
2543 /* ??? Fails because of a MIPS assembler bug? */
2544 else if (TARGET_64BIT
&& bytes
>= 8)
2546 #if BYTES_BIG_ENDIAN
2547 load_store
[num
].load
= "ldl\t%0,%1\n\tldr\t%0,%2";
2548 load_store
[num
].load_nop
= "ldl\t%0,%1\n\tldr\t%0,%2%#";
2549 load_store
[num
].store
= "sdl\t%0,%1\n\tsdr\t%0,%2";
2550 load_store
[num
].last_store
= "sdr\t%0,%2";
2551 load_store
[num
].final
= "sdl\t%0,%1";
2553 load_store
[num
].load
= "ldl\t%0,%2\n\tldr\t%0,%1";
2554 load_store
[num
].load_nop
= "ldl\t%0,%2\n\tldr\t%0,%1%#";
2555 load_store
[num
].store
= "sdl\t%0,%2\n\tsdr\t%0,%1";
2556 load_store
[num
].last_store
= "sdr\t%0,%1";
2557 load_store
[num
].final
= "sdl\t%0,%2";
2559 load_store
[num
].mode
= DImode
;
2565 else if (bytes
>= 4 && align
>= 4)
2567 load_store
[num
].load
= "lw\t%0,%1";
2568 load_store
[num
].load_nop
= "lw\t%0,%1%#";
2569 load_store
[num
].store
= "sw\t%0,%1";
2570 load_store
[num
].last_store
= "sw\t%0,%1";
2571 load_store
[num
].final
= (char *)0;
2572 load_store
[num
].mode
= SImode
;
2577 else if (bytes
>= 4)
2579 #if BYTES_BIG_ENDIAN
2580 load_store
[num
].load
= "lwl\t%0,%1\n\tlwr\t%0,%2";
2581 load_store
[num
].load_nop
= "lwl\t%0,%1\n\tlwr\t%0,%2%#";
2582 load_store
[num
].store
= "swl\t%0,%1\n\tswr\t%0,%2";
2583 load_store
[num
].last_store
= "swr\t%0,%2";
2584 load_store
[num
].final
= "swl\t%0,%1";
2586 load_store
[num
].load
= "lwl\t%0,%2\n\tlwr\t%0,%1";
2587 load_store
[num
].load_nop
= "lwl\t%0,%2\n\tlwr\t%0,%1%#";
2588 load_store
[num
].store
= "swl\t%0,%2\n\tswr\t%0,%1";
2589 load_store
[num
].last_store
= "swr\t%0,%1";
2590 load_store
[num
].final
= "swl\t%0,%2";
2592 load_store
[num
].mode
= SImode
;
2598 else if (bytes
>= 2 && align
>= 2)
2600 load_store
[num
].load
= "lh\t%0,%1";
2601 load_store
[num
].load_nop
= "lh\t%0,%1%#";
2602 load_store
[num
].store
= "sh\t%0,%1";
2603 load_store
[num
].last_store
= "sh\t%0,%1";
2604 load_store
[num
].final
= (char *)0;
2605 load_store
[num
].mode
= HImode
;
2612 load_store
[num
].load
= "lb\t%0,%1";
2613 load_store
[num
].load_nop
= "lb\t%0,%1%#";
2614 load_store
[num
].store
= "sb\t%0,%1";
2615 load_store
[num
].last_store
= "sb\t%0,%1";
2616 load_store
[num
].final
= (char *)0;
2617 load_store
[num
].mode
= QImode
;
2622 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2624 dslots_load_total
++;
2625 dslots_load_filled
++;
2627 if (CONSTANT_P (src_reg
))
2628 mips_count_memory_refs (src_reg
, 1);
2630 if (CONSTANT_P (dest_reg
))
2631 mips_count_memory_refs (dest_reg
, 1);
2634 /* Emit load/stores now if we have run out of registers or are
2635 at the end of the move. */
2637 if (++num
== num_regs
|| bytes
== 0)
2639 /* If only load/store, we need a NOP after the load. */
2642 load_store
[0].load
= load_store
[0].load_nop
;
2643 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2644 dslots_load_filled
--;
2647 if (move_type
!= BLOCK_MOVE_LAST
)
2649 for (i
= 0; i
< num
; i
++)
2656 if (GET_MODE (operands
[i
+4]) != load_store
[i
].mode
)
2657 operands
[i
+4] = gen_rtx (REG
, load_store
[i
].mode
, REGNO (operands
[i
+4]));
2659 offset
= load_store
[i
].offset
;
2660 xoperands
[0] = operands
[i
+4];
2661 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2662 plus_constant (src_reg
, offset
));
2667 extra_offset
= GET_MODE_SIZE (load_store
[i
].mode
) - 1;
2668 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2669 plus_constant (src_reg
,
2674 output_asm_insn (load_store
[i
].load
, xoperands
);
2678 for (i
= 0; i
< num
; i
++)
2680 int last_p
= (i
== num
-1 && bytes
== 0);
2681 int offset
= load_store
[i
].offset
;
2683 xoperands
[0] = operands
[i
+4];
2684 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2685 plus_constant (dest_reg
, offset
));
2691 extra_offset
= GET_MODE_SIZE (load_store
[i
].mode
) - 1;
2692 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2693 plus_constant (dest_reg
,
2698 if (move_type
== BLOCK_MOVE_NORMAL
)
2699 output_asm_insn (load_store
[i
].store
, xoperands
);
2701 else if (move_type
== BLOCK_MOVE_NOT_LAST
)
2704 output_asm_insn (load_store
[i
].store
, xoperands
);
2706 else if (load_store
[i
].final
!= (char *)0)
2707 output_asm_insn (load_store
[i
].final
, xoperands
);
2711 output_asm_insn (load_store
[i
].last_store
, xoperands
);
2714 num
= 0; /* reset load_store */
2715 use_lwl_lwr
= FALSE
;
2719 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& --set_noreorder
== 0)
2720 output_asm_insn (".set\treorder", operands
);
2726 /* Argument support functions. */
2728 /* Initialize CUMULATIVE_ARGS for a function. */
2731 init_cumulative_args (cum
, fntype
, libname
)
2732 CUMULATIVE_ARGS
*cum
; /* argument info to initialize */
2733 tree fntype
; /* tree ptr for function decl */
2734 rtx libname
; /* SYMBOL_REF of library name or 0 */
2736 static CUMULATIVE_ARGS zero_cum
;
2737 tree param
, next_param
;
2739 if (TARGET_DEBUG_E_MODE
)
2741 fprintf (stderr
, "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype
);
2743 fputc ('\n', stderr
);
2747 tree ret_type
= TREE_TYPE (fntype
);
2748 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
2749 tree_code_name
[ (int)TREE_CODE (fntype
) ],
2750 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
2756 /* Determine if this function has variable arguments. This is
2757 indicated by the last argument being 'void_type_mode' if there
2758 are no variable arguments. The standard MIPS calling sequence
2759 passes all arguments in the general purpose registers in this
2762 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
2766 next_param
= TREE_CHAIN (param
);
2767 if (next_param
== (tree
)0 && TREE_VALUE (param
) != void_type_node
)
2768 cum
->gp_reg_found
= 1;
2772 /* Advance the argument to the next argument position. */
2775 function_arg_advance (cum
, mode
, type
, named
)
2776 CUMULATIVE_ARGS
*cum
; /* current arg information */
2777 enum machine_mode mode
; /* current arg mode */
2778 tree type
; /* type of the argument or 0 if lib support */
2779 int named
; /* whether or not the argument was named */
2781 if (TARGET_DEBUG_E_MODE
)
2783 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n\n",
2784 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2794 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
2795 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
2797 cum
->gp_reg_found
= 1;
2798 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
2803 cum
->gp_reg_found
= 1;
2804 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
2813 cum
->arg_words
+= (TARGET_64BIT
? 1 : 2);
2817 cum
->gp_reg_found
= 1;
2818 cum
->arg_words
+= (TARGET_64BIT
? 1 : 2);
2824 cum
->gp_reg_found
= 1;
2830 /* Return an RTL expression containing the register for the given mode,
2831 or 0 if the argument is to be passed on the stack. */
2834 function_arg (cum
, mode
, type
, named
)
2835 CUMULATIVE_ARGS
*cum
; /* current arg information */
2836 enum machine_mode mode
; /* current arg mode */
2837 tree type
; /* type of the argument or 0 if lib support */
2838 int named
; /* != 0 for normal args, == 0 for ... args */
2843 int struct_p
= ((type
!= (tree
)0)
2844 && (TREE_CODE (type
) == RECORD_TYPE
2845 || TREE_CODE (type
) == UNION_TYPE
));
2847 if (TARGET_DEBUG_E_MODE
)
2849 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ",
2850 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2856 if (cum
->gp_reg_found
|| cum
->arg_number
>= 2 || TARGET_SOFT_FLOAT
)
2857 regbase
= GP_ARG_FIRST
;
2860 regbase
= FP_ARG_FIRST
;
2861 /* If the first arg was a float in a floating point register,
2862 then set bias to align this float arg properly. */
2863 if (cum
->arg_words
== 1)
2871 cum
->arg_words
+= (cum
->arg_words
& 1);
2872 regbase
= (cum
->gp_reg_found
|| TARGET_SOFT_FLOAT
|| cum
->arg_number
>= 2
2878 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
2879 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
2882 /* Drops through. */
2884 if (type
!= (tree
)0 && TYPE_ALIGN (type
) > BITS_PER_WORD
2886 cum
->arg_words
+= (cum
->arg_words
& 1);
2888 regbase
= GP_ARG_FIRST
;
2895 regbase
= GP_ARG_FIRST
;
2900 cum
->arg_words
+= (cum
->arg_words
& 1);
2901 regbase
= GP_ARG_FIRST
;
2904 if (cum
->arg_words
>= MAX_ARGS_IN_REGISTERS
)
2906 if (TARGET_DEBUG_E_MODE
)
2907 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
2916 ret
= gen_rtx (REG
, mode
, regbase
+ cum
->arg_words
+ bias
);
2918 if (TARGET_DEBUG_E_MODE
)
2919 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ cum
->arg_words
+ bias
],
2920 struct_p
? ", [struct]" : "");
2922 /* The following is a hack in order to pass 1 byte structures
2923 the same way that the MIPS compiler does (namely by passing
2924 the structure in the high byte or half word of the register).
2925 This also makes varargs work. If we have such a structure,
2926 we save the adjustment RTL, and the call define expands will
2927 emit them. For the VOIDmode argument (argument after the
2928 last real argument), pass back a parallel vector holding each
2929 of the adjustments. */
2931 /* ??? function_arg can be called more than once for each argument.
2932 As a result, we compute more adjustments than we need here.
2933 See the CUMULATIVE_ARGS definition in mips.h. */
2935 /* ??? This scheme requires everything smaller than the word size to
2936 shifted to the left, but when TARGET_64BIT and ! TARGET_INT64,
2937 that would mean every int needs to be shifted left, which is very
2938 inefficient. Let's not carry this compatibility to the 64 bit
2939 calling convention for now. */
2941 if (struct_p
&& int_size_in_bytes (type
) < UNITS_PER_WORD
2944 rtx amount
= GEN_INT (BITS_PER_WORD
2945 - int_size_in_bytes (type
) * BITS_PER_UNIT
);
2946 rtx reg
= gen_rtx (REG
, word_mode
, regbase
+ cum
->arg_words
+ bias
);
2948 cum
->adjust
[ cum
->num_adjusts
++ ] = gen_ashldi3 (reg
, reg
, amount
);
2950 cum
->adjust
[ cum
->num_adjusts
++ ] = gen_ashlsi3 (reg
, reg
, amount
);
2954 if (mode
== VOIDmode
&& cum
->num_adjusts
> 0)
2955 ret
= gen_rtx (PARALLEL
, VOIDmode
, gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
2962 function_arg_partial_nregs (cum
, mode
, type
, named
)
2963 CUMULATIVE_ARGS
*cum
; /* current arg information */
2964 enum machine_mode mode
; /* current arg mode */
2965 tree type
; /* type of the argument or 0 if lib support */
2966 int named
; /* != 0 for normal args, == 0 for ... args */
2968 if ((mode
== BLKmode
2969 || GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
2970 || GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
2971 && cum
->arg_words
< MAX_ARGS_IN_REGISTERS
)
2974 if (mode
== BLKmode
)
2975 words
= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
2978 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2980 if (words
+ cum
->arg_words
<= MAX_ARGS_IN_REGISTERS
)
2981 return 0; /* structure fits in registers */
2983 if (TARGET_DEBUG_E_MODE
)
2984 fprintf (stderr
, "function_arg_partial_nregs = %d\n",
2985 MAX_ARGS_IN_REGISTERS
- cum
->arg_words
);
2987 return MAX_ARGS_IN_REGISTERS
- cum
->arg_words
;
2990 else if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
-1
2993 if (TARGET_DEBUG_E_MODE
)
2994 fprintf (stderr
, "function_arg_partial_nregs = 1\n");
3003 /* Print the options used in the assembly file. */
3005 static struct {char *name
; int value
;} target_switches
[]
3016 int mask
= TARGET_DEFAULT
;
3018 /* Allow assembly language comparisons with -mdebug eliminating the
3019 compiler version number and switch lists. */
3021 if (TARGET_DEBUG_MODE
)
3024 fprintf (out
, "\n # %s %s", language_string
, version_string
);
3025 #ifdef TARGET_VERSION_INTERNAL
3026 TARGET_VERSION_INTERNAL (out
);
3029 fprintf (out
, " compiled by GNU C\n\n");
3031 fprintf (out
, " compiled by CC\n\n");
3034 fprintf (out
, " # Cc1 defaults:");
3036 for (j
= 0; j
< sizeof target_switches
/ sizeof target_switches
[0]; j
++)
3038 if (target_switches
[j
].name
[0] != '\0'
3039 && target_switches
[j
].value
> 0
3040 && (target_switches
[j
].value
& mask
) == target_switches
[j
].value
)
3042 mask
&= ~ target_switches
[j
].value
;
3043 len
= strlen (target_switches
[j
].name
) + 1;
3044 if (len
+ line_len
> 79)
3047 fputs ("\n #", out
);
3049 fprintf (out
, " -m%s", target_switches
[j
].name
);
3054 fprintf (out
, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):",
3055 mips_section_threshold
, mips_cpu_string
, mips_isa
);
3058 for (p
= &save_argv
[1]; *p
!= (char *)0; p
++)
3063 len
= strlen (arg
) + 1;
3064 if (len
+ line_len
> 79)
3067 fputs ("\n #", out
);
3069 fprintf (out
, " %s", *p
);
3074 fputs ("\n\n", out
);
3078 /* Abort after printing out a specific insn. */
3081 abort_with_insn (insn
, reason
)
3090 /* Write a message to stderr (for use in macros expanded in files that do not
3091 include stdio.h). */
3097 fprintf (stderr
, s
, s1
, s2
);
3107 fprintf (stderr
, "compiling '%s' in '%s'\n",
3108 (current_function_name
!= (char *)0) ? current_function_name
: "<toplevel>",
3109 (current_function_file
!= (char *)0) ? current_function_file
: "<no file>");
3112 #endif /* SIGINFO */
3115 /* Set up the threshold for data to go into the small data area, instead
3116 of the normal data area, and detect any conflicts in the switches. */
3121 register int i
, start
;
3123 register enum machine_mode mode
;
3125 mips_section_threshold
= (g_switch_set
) ? g_switch_value
: MIPS_DEFAULT_GVALUE
;
3127 if (mips_section_threshold
<= 0)
3128 target_flags
&= ~MASK_GPOPT
;
3130 target_flags
|= MASK_GPOPT
;
3132 /* Get the architectural level. */
3133 if (mips_isa_string
== (char *)0)
3135 #ifdef MIPS_ISA_DEFAULT
3136 mips_isa
= MIPS_ISA_DEFAULT
;
3142 else if (isdigit (*mips_isa_string
))
3144 mips_isa
= atoi (mips_isa_string
);
3145 if (mips_isa
< 1 || mips_isa
> 3)
3147 error ("-mips%d not supported", mips_isa
);
3154 error ("bad value (%s) for -mips switch", mips_isa_string
);
3158 /* Identify the processor type */
3159 if (mips_cpu_string
== (char *)0
3160 || !strcmp (mips_cpu_string
, "default")
3161 || !strcmp (mips_cpu_string
, "DEFAULT"))
3166 mips_cpu_string
= "3000";
3167 mips_cpu
= PROCESSOR_R3000
;
3170 mips_cpu_string
= "6000";
3171 mips_cpu
= PROCESSOR_R6000
;
3174 mips_cpu_string
= "4000";
3175 mips_cpu
= PROCESSOR_R4000
;
3182 char *p
= mips_cpu_string
;
3184 if (*p
== 'r' || *p
== 'R')
3187 /* Since there is no difference between a R2000 and R3000 in
3188 terms of the scheduler, we collapse them into just an R3000. */
3190 mips_cpu
= PROCESSOR_DEFAULT
;
3194 if (!strcmp (p
, "2000") || !strcmp (p
, "2k") || !strcmp (p
, "2K"))
3195 mips_cpu
= PROCESSOR_R3000
;
3199 if (!strcmp (p
, "3000") || !strcmp (p
, "3k") || !strcmp (p
, "3K"))
3200 mips_cpu
= PROCESSOR_R3000
;
3204 if (!strcmp (p
, "4000") || !strcmp (p
, "4k") || !strcmp (p
, "4K"))
3205 mips_cpu
= PROCESSOR_R4000
;
3206 /* The r4400 is exactly the same as the r4000 from the compiler's
3208 else if (!strcmp (p
, "4400"))
3209 mips_cpu
= PROCESSOR_R4000
;
3210 else if (!strcmp (p
, "4600"))
3211 mips_cpu
= PROCESSOR_R4600
;
3215 if (!strcmp (p
, "6000") || !strcmp (p
, "6k") || !strcmp (p
, "6K"))
3216 mips_cpu
= PROCESSOR_R6000
;
3220 if (!strcmp (p
, "orion"))
3221 mips_cpu
= PROCESSOR_R4600
;
3225 if (mips_cpu
== PROCESSOR_DEFAULT
)
3227 error ("bad value (%s) for -mcpu= switch", mips_cpu_string
);
3228 mips_cpu_string
= "default";
3232 if ((mips_cpu
== PROCESSOR_R3000
&& mips_isa
> 1)
3233 || (mips_cpu
== PROCESSOR_R6000
&& mips_isa
> 2))
3234 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
3236 /* make sure sizes of ints/longs/etc. are ok */
3240 fatal ("Only MIPS-III CPUs can support 64 bit ints");
3242 else if (TARGET_LONG64
)
3243 fatal ("Only MIPS-III CPUs can support 64 bit longs");
3245 else if (TARGET_LLONG128
)
3246 fatal ("Only MIPS-III CPUs can support 128 bit long longs");
3248 else if (TARGET_FLOAT64
)
3249 fatal ("Only MIPS-III CPUs can support 64 bit fp registers");
3251 else if (TARGET_64BIT
)
3252 fatal ("Only MIPS-III CPUs can support 64 bit gp registers");
3256 if (TARGET_LLONG128
)
3257 fatal ("128 bit long longs are not supported");
3260 /* Tell halfpic.c that we have half-pic code if we do. */
3261 if (TARGET_HALF_PIC
)
3264 /* -fpic (-KPIC) is the default when TARGET_ABICALLS is defined. We need
3265 to set flag_pic so that the LEGITIMATE_PIC_OPERAND_P macro will work. */
3266 /* ??? -non_shared turns off pic code generation, but this is not
3268 if (TARGET_ABICALLS
)
3270 mips_abicalls
= MIPS_ABICALLS_YES
;
3272 if (mips_section_threshold
> 0)
3273 warning ("-G is incompatible with PIC code which is the default");
3276 mips_abicalls
= MIPS_ABICALLS_NO
;
3278 /* -mrnames says to use the MIPS software convention for register
3279 names instead of the hardware names (ie, $a0 instead of $4).
3280 We do this by switching the names in mips_reg_names, which the
3281 reg_names points into via the REGISTER_NAMES macro. */
3283 if (TARGET_NAME_REGS
)
3284 bcopy ((char *) mips_sw_reg_names
, (char *) mips_reg_names
, sizeof (mips_reg_names
));
3286 /* If this is OSF/1, set up a SIGINFO handler so we can see what function
3287 is currently being compiled. */
3289 if (getenv ("GCC_SIGINFO") != (char *)0)
3291 struct sigaction action
;
3292 action
.sa_handler
= siginfo
;
3294 action
.sa_flags
= SA_RESTART
;
3295 sigaction (SIGINFO
, &action
, (struct sigaction
*)0);
3300 #if defined(ultrix) || defined(__ultrix) || defined(__OSF1__) || defined(__osf__) || defined(osf)
3301 /* If -mstats and -quiet, make stderr line buffered. */
3302 if (quiet_flag
&& TARGET_STATS
)
3303 setvbuf (stderr
, (char *)0, _IOLBF
, BUFSIZ
);
3307 /* Initialize the high and low values for legitimate floating point
3308 constants. Rather than trying to get the accuracy down to the
3309 last bit, just use approximate ranges. */
3310 dfhigh
= REAL_VALUE_ATOF ("1.0e300", DFmode
);
3311 dflow
= REAL_VALUE_ATOF ("1.0e-300", DFmode
);
3312 sfhigh
= REAL_VALUE_ATOF ("1.0e38", SFmode
);
3313 sflow
= REAL_VALUE_ATOF ("1.0e-38", SFmode
);
3315 /* Set up the classification arrays now. */
3316 mips_rtx_classify
[(int)PLUS
] = CLASS_ADD_OP
;
3317 mips_rtx_classify
[(int)MINUS
] = CLASS_ADD_OP
;
3318 mips_rtx_classify
[(int)DIV
] = CLASS_DIVMOD_OP
;
3319 mips_rtx_classify
[(int)MOD
] = CLASS_DIVMOD_OP
;
3320 mips_rtx_classify
[(int)UDIV
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
3321 mips_rtx_classify
[(int)UMOD
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
3322 mips_rtx_classify
[(int)EQ
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
3323 mips_rtx_classify
[(int)NE
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
3324 mips_rtx_classify
[(int)GT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
3325 mips_rtx_classify
[(int)GE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
3326 mips_rtx_classify
[(int)LT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
3327 mips_rtx_classify
[(int)LE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
3328 mips_rtx_classify
[(int)GTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
3329 mips_rtx_classify
[(int)GEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
3330 mips_rtx_classify
[(int)LTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
3331 mips_rtx_classify
[(int)LEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
3333 mips_print_operand_punct
['?'] = TRUE
;
3334 mips_print_operand_punct
['#'] = TRUE
;
3335 mips_print_operand_punct
['&'] = TRUE
;
3336 mips_print_operand_punct
['!'] = TRUE
;
3337 mips_print_operand_punct
['*'] = TRUE
;
3338 mips_print_operand_punct
['@'] = TRUE
;
3339 mips_print_operand_punct
['.'] = TRUE
;
3340 mips_print_operand_punct
['('] = TRUE
;
3341 mips_print_operand_punct
[')'] = TRUE
;
3342 mips_print_operand_punct
['['] = TRUE
;
3343 mips_print_operand_punct
[']'] = TRUE
;
3344 mips_print_operand_punct
['<'] = TRUE
;
3345 mips_print_operand_punct
['>'] = TRUE
;
3346 mips_print_operand_punct
['{'] = TRUE
;
3347 mips_print_operand_punct
['}'] = TRUE
;
3348 mips_print_operand_punct
['^'] = TRUE
;
3350 mips_char_to_class
['d'] = GR_REGS
;
3351 mips_char_to_class
['f'] = ((TARGET_HARD_FLOAT
) ? FP_REGS
: NO_REGS
);
3352 mips_char_to_class
['h'] = HI_REG
;
3353 mips_char_to_class
['l'] = LO_REG
;
3354 mips_char_to_class
['x'] = MD_REGS
;
3355 mips_char_to_class
['y'] = GR_REGS
;
3356 mips_char_to_class
['z'] = ST_REGS
;
3358 /* Set up array to map GCC register number to debug register number.
3359 Ignore the special purpose register numbers. */
3361 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3362 mips_dbx_regno
[i
] = -1;
3364 start
= GP_DBX_FIRST
- GP_REG_FIRST
;
3365 for (i
= GP_REG_FIRST
; i
<= GP_REG_LAST
; i
++)
3366 mips_dbx_regno
[i
] = i
+ start
;
3368 start
= FP_DBX_FIRST
- FP_REG_FIRST
;
3369 for (i
= FP_REG_FIRST
; i
<= FP_REG_LAST
; i
++)
3370 mips_dbx_regno
[i
] = i
+ start
;
3372 /* Set up array giving whether a given register can hold a given mode.
3373 At present, restrict ints from being in FP registers, because reload
3374 is a little enthusiastic about storing extra values in FP registers,
3375 and this is not good for things like OS kernels. Also, due to the
3376 mandatory delay, it is as fast to load from cached memory as to move
3377 from the FP register. */
3379 for (mode
= VOIDmode
;
3380 mode
!= MAX_MACHINE_MODE
;
3381 mode
= (enum machine_mode
)((int)mode
+ 1))
3383 register int size
= GET_MODE_SIZE (mode
);
3384 register enum mode_class
class = GET_MODE_CLASS (mode
);
3386 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
3390 if (mode
== CC_FPmode
|| mode
== CC_REV_FPmode
)
3391 temp
= (regno
== FPSW_REGNUM
);
3393 else if (GP_REG_P (regno
))
3394 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
3396 else if (FP_REG_P (regno
))
3397 temp
= ((TARGET_FLOAT64
|| ((regno
& 1) == 0))
3398 && (class == MODE_FLOAT
3399 || class == MODE_COMPLEX_FLOAT
3400 || (TARGET_DEBUG_H_MODE
&& class == MODE_INT
)));
3402 else if (MD_REG_P (regno
))
3405 temp
= (mode
== DImode
3406 || (regno
== MD_REG_FIRST
&& mode
== TImode
));
3408 temp
= (mode
== SImode
3409 || (regno
== MD_REG_FIRST
&& mode
== DImode
));
3415 mips_hard_regno_mode_ok
[(int)mode
][regno
] = temp
;
3422 * The MIPS debug format wants all automatic variables and arguments
3423 * to be in terms of the virtual frame pointer (stack pointer before
3424 * any adjustment in the function), while the MIPS 3.0 linker wants
3425 * the frame pointer to be the stack pointer after the initial
3426 * adjustment. So, we do the adjustment here. The arg pointer (which
3427 * is eliminated) points to the virtual frame pointer, while the frame
3428 * pointer (which may be eliminated) points to the stack pointer after
3429 * the initial adjustments.
3433 mips_debugger_offset (addr
, offset
)
3437 rtx offset2
= const0_rtx
;
3438 rtx reg
= eliminate_constant_term (addr
, &offset2
);
3441 offset
= INTVAL (offset2
);
3443 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
)
3445 int frame_size
= (!current_frame_info
.initialized
)
3446 ? compute_frame_size (get_frame_size ())
3447 : current_frame_info
.total_size
;
3449 offset
= offset
- frame_size
;
3451 /* sdbout_parms does not want this to crash for unrecognized cases. */
3453 else if (reg
!= arg_pointer_rtx
)
3454 abort_with_insn (addr
, "mips_debugger_offset called with non stack/frame/arg pointer.");
3461 /* A C compound statement to output to stdio stream STREAM the
3462 assembler syntax for an instruction operand X. X is an RTL
3465 CODE is a value that can be used to specify one of several ways
3466 of printing the operand. It is used when identical operands
3467 must be printed differently depending on the context. CODE
3468 comes from the `%' specification that was used to request
3469 printing of the operand. If the specification was just `%DIGIT'
3470 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3471 is the ASCII code for LTR.
3473 If X is a register, this macro should print the register's name.
3474 The names can be found in an array `reg_names' whose type is
3475 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3477 When the machine description has a specification `%PUNCT' (a `%'
3478 followed by a punctuation character), this macro is called with
3479 a null pointer for X and the punctuation character for CODE.
3481 The MIPS specific codes are:
3483 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
3484 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
3485 'd' output integer constant in decimal,
3486 'z' if the operand is 0, use $0 instead of normal operand.
3487 'D' print second register of double-word register operand.
3488 'L' print low-order register of double-word register operand.
3489 'M' print high-order register of double-word register operand.
3490 'C' print part of opcode for a branch condition.
3491 'N' print part of opcode for a branch condition, inverted.
3492 '(' Turn on .set noreorder
3493 ')' Turn on .set reorder
3494 '[' Turn on .set noat
3496 '<' Turn on .set nomacro
3497 '>' Turn on .set macro
3498 '{' Turn on .set volatile (not GAS)
3499 '}' Turn on .set novolatile (not GAS)
3500 '&' Turn on .set noreorder if filling delay slots
3501 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
3502 '!' Turn on .set nomacro if filling delay slots
3503 '#' Print nop if in a .set noreorder section.
3504 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3505 '@' Print the name of the assembler temporary register (at or $1).
3506 '.' Print the name of the register with a hard-wired zero (zero or $0).
3507 '^' Print the name of the pic call-through register (t9 or $25). */
3510 print_operand (file
, op
, letter
)
3511 FILE *file
; /* file to write to */
3512 rtx op
; /* operand to print */
3513 int letter
; /* %<letter> or 0 */
3515 register enum rtx_code code
;
3517 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3522 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3526 if (mips_branch_likely
)
3531 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3535 fputs (reg_names
[PIC_FUNCTION_ADDR_REGNUM
], file
);
3539 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3543 if (final_sequence
!= 0 && set_noreorder
++ == 0)
3544 fputs (".set\tnoreorder\n\t", file
);
3548 if (final_sequence
!= 0)
3550 if (set_noreorder
++ == 0)
3551 fputs (".set\tnoreorder\n\t", file
);
3553 if (set_nomacro
++ == 0)
3554 fputs (".set\tnomacro\n\t", file
);
3559 if (final_sequence
!= 0 && set_nomacro
++ == 0)
3560 fputs ("\n\t.set\tnomacro", file
);
3564 if (set_noreorder
!= 0)
3565 fputs ("\n\tnop", file
);
3567 else if (TARGET_GAS
|| TARGET_STATS
)
3568 fputs ("\n\t#nop", file
);
3573 if (set_noreorder
++ == 0)
3574 fputs (".set\tnoreorder\n\t", file
);
3578 if (set_noreorder
== 0)
3579 error ("internal error: %%) found without a %%( in assembler pattern");
3581 else if (--set_noreorder
== 0)
3582 fputs ("\n\t.set\treorder", file
);
3587 if (set_noat
++ == 0)
3588 fputs (".set\tnoat\n\t", file
);
3593 error ("internal error: %%] found without a %%[ in assembler pattern");
3595 else if (--set_noat
== 0)
3596 fputs ("\n\t.set\tat", file
);
3601 if (set_nomacro
++ == 0)
3602 fputs (".set\tnomacro\n\t", file
);
3606 if (set_nomacro
== 0)
3607 error ("internal error: %%> found without a %%< in assembler pattern");
3609 else if (--set_nomacro
== 0)
3610 fputs ("\n\t.set\tmacro", file
);
3615 if (set_volatile
++ == 0)
3616 fprintf (file
, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS
) ? "" : "#");
3620 if (set_volatile
== 0)
3621 error ("internal error: %%} found without a %%{ in assembler pattern");
3623 else if (--set_volatile
== 0)
3624 fprintf (file
, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS
) ? "" : "#");
3633 error ("PRINT_OPERAND null pointer");
3637 code
= GET_CODE (op
);
3641 case EQ
: fputs ("eq", file
); break;
3642 case NE
: fputs ("ne", file
); break;
3643 case GT
: fputs ("gt", file
); break;
3644 case GE
: fputs ("ge", file
); break;
3645 case LT
: fputs ("lt", file
); break;
3646 case LE
: fputs ("le", file
); break;
3647 case GTU
: fputs ("gtu", file
); break;
3648 case GEU
: fputs ("geu", file
); break;
3649 case LTU
: fputs ("ltu", file
); break;
3650 case LEU
: fputs ("leu", file
); break;
3653 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%C");
3656 else if (letter
== 'N')
3659 case EQ
: fputs ("ne", file
); break;
3660 case NE
: fputs ("eq", file
); break;
3661 case GT
: fputs ("le", file
); break;
3662 case GE
: fputs ("lt", file
); break;
3663 case LT
: fputs ("ge", file
); break;
3664 case LE
: fputs ("gt", file
); break;
3665 case GTU
: fputs ("leu", file
); break;
3666 case GEU
: fputs ("ltu", file
); break;
3667 case LTU
: fputs ("geu", file
); break;
3668 case LEU
: fputs ("gtu", file
); break;
3671 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%N");
3674 else if (code
== REG
)
3676 register int regnum
= REGNO (op
);
3679 regnum
+= MOST_SIGNIFICANT_WORD
;
3681 else if (letter
== 'L')
3682 regnum
+= LEAST_SIGNIFICANT_WORD
;
3684 else if (letter
== 'D')
3687 fprintf (file
, "%s", reg_names
[regnum
]);
3690 else if (code
== MEM
)
3691 output_address (XEXP (op
, 0));
3693 else if (code
== CONST_DOUBLE
)
3698 REAL_VALUE_FROM_CONST_DOUBLE (d
, op
);
3699 REAL_VALUE_TO_DECIMAL (d
, "%.20e", s
);
3703 else if ((letter
== 'x') && (GET_CODE(op
) == CONST_INT
))
3704 fprintf (file
, "0x%04x", 0xffff & (INTVAL(op
)));
3706 else if ((letter
== 'X') && (GET_CODE(op
) == CONST_INT
))
3707 fprintf (file
, "0x%08x", INTVAL(op
));
3709 else if ((letter
== 'd') && (GET_CODE(op
) == CONST_INT
))
3710 fprintf (file
, "%d", (INTVAL(op
)));
3712 else if (letter
== 'z'
3713 && (GET_CODE (op
) == CONST_INT
)
3714 && INTVAL (op
) == 0)
3715 fputs (reg_names
[GP_REG_FIRST
], file
);
3717 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3718 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter
);
3721 output_addr_const (file
, op
);
3725 /* A C compound statement to output to stdio stream STREAM the
3726 assembler syntax for an instruction operand that is a memory
3727 reference whose address is ADDR. ADDR is an RTL expression.
3729 On some machines, the syntax for a symbolic address depends on
3730 the section that the address refers to. On these machines,
3731 define the macro `ENCODE_SECTION_INFO' to store the information
3732 into the `symbol_ref', and then check for it here. */
3735 print_operand_address (file
, addr
)
3740 error ("PRINT_OPERAND_ADDRESS, null pointer");
3743 switch (GET_CODE (addr
))
3746 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #1");
3750 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3751 abort_with_insn (addr
, "Arg pointer not eliminated.");
3753 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
3758 register rtx reg
= (rtx
)0;
3759 register rtx offset
= (rtx
)0;
3760 register rtx arg0
= XEXP (addr
, 0);
3761 register rtx arg1
= XEXP (addr
, 1);
3763 if (GET_CODE (arg0
) == REG
)
3767 if (GET_CODE (offset
) == REG
)
3768 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
3770 else if (GET_CODE (arg1
) == REG
)
3775 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
3777 output_addr_const (file
, addr
);
3781 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3783 if (!CONSTANT_P (offset
))
3784 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #2");
3786 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3787 abort_with_insn (addr
, "Arg pointer not eliminated.");
3789 output_addr_const (file
, offset
);
3790 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3798 output_addr_const (file
, addr
);
3804 /* If optimizing for the global pointer, keep track of all of
3805 the externs, so that at the end of the file, we can emit
3806 the appropriate .extern declaration for them, before writing
3807 out the text section. We assume that all names passed to
3808 us are in the permanent obstack, so that they will be valid
3809 at the end of the compilation.
3811 If we have -G 0, or the extern size is unknown, don't bother
3812 emitting the .externs. */
3815 mips_output_external (file
, decl
, name
)
3820 register struct extern_list
*p
;
3824 && ((TREE_CODE (decl
)) != FUNCTION_DECL
)
3825 && ((len
= int_size_in_bytes (TREE_TYPE (decl
))) > 0))
3827 p
= (struct extern_list
*)permalloc ((long) sizeof (struct extern_list
));
3828 p
->next
= extern_head
;
3837 /* Compute a string to use as a temporary file name. */
3839 /* On MSDOS, write temp files in current dir
3840 because there's no place else we can expect to use. */
3843 #define P_tmpdir "./"
3851 char *base
= getenv ("TMPDIR");
3854 if (base
== (char *)0)
3857 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
3861 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
3867 len
= strlen (base
);
3868 /* temp_filename is global, so we must use malloc, not alloca. */
3869 temp_filename
= (char *) xmalloc (len
+ sizeof("/ctXXXXXX"));
3870 strcpy (temp_filename
, base
);
3871 if (len
> 0 && temp_filename
[len
-1] != '/')
3872 temp_filename
[len
++] = '/';
3874 strcpy (temp_filename
+ len
, "ctXXXXXX");
3875 mktemp (temp_filename
);
3877 stream
= fopen (temp_filename
, "w+");
3879 pfatal_with_name (temp_filename
);
3882 /* In MSDOS, we cannot unlink the temporary file until we are finished using
3883 it. Otherwise, we delete it now, so that it will be gone even if the
3884 compiler happens to crash. */
3885 unlink (temp_filename
);
3891 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out
3892 for .file's that start within a function. If we are smuggling stabs, try to
3893 put out a MIPS ECOFF file and a stab. */
3896 mips_output_filename (stream
, name
)
3900 static int first_time
= TRUE
;
3901 char ltext_label_name
[100];
3907 current_function_file
= name
;
3908 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
3909 output_quoted_string (stream
, name
);
3910 fprintf (stream
, "\n");
3911 /* This tells mips-tfile that stabs will follow. */
3912 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3913 fprintf (stream
, "\t#@stabs\n");
3916 else if (write_symbols
== DBX_DEBUG
)
3918 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
3919 fprintf (stream
, "%s ", ASM_STABS_OP
);
3920 output_quoted_string (stream
, name
);
3921 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
3924 else if (name
!= current_function_file
3925 && strcmp (name
, current_function_file
) != 0)
3927 if (inside_function
&& !TARGET_GAS
)
3929 if (!file_in_function_warning
)
3931 file_in_function_warning
= TRUE
;
3932 ignore_line_number
= TRUE
;
3933 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line");
3936 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
3942 current_function_file
= name
;
3943 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
3945 output_quoted_string (stream
, name
);
3946 fprintf (stream
, "\n");
3951 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
3952 as well as a .loc, since it is possible that MIPS ECOFF might not be
3953 able to represent the location for inlines that come from a different
3957 mips_output_lineno (stream
, line
)
3961 if (write_symbols
== DBX_DEBUG
)
3964 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3965 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
3970 fprintf (stream
, "\n\t%s.loc\t%d %d\n",
3971 (ignore_line_number
) ? "#" : "",
3972 num_source_filenames
, line
);
3974 LABEL_AFTER_LOC (stream
);
3979 /* If defined, a C statement to be executed just prior to the
3980 output of assembler code for INSN, to modify the extracted
3981 operands so they will be output differently.
3983 Here the argument OPVEC is the vector containing the operands
3984 extracted from INSN, and NOPERANDS is the number of elements of
3985 the vector which contain meaningful data for this insn. The
3986 contents of this vector are what will be used to convert the
3987 insn template into assembler code, so you can change the
3988 assembler output by changing the contents of the vector.
3990 We use it to check if the current insn needs a nop in front of it
3991 because of load delays, and also to update the delay slot
3995 final_prescan_insn (insn
, opvec
, noperands
)
4000 if (dslots_number_nops
> 0)
4002 rtx pattern
= PATTERN (insn
);
4003 int length
= get_attr_length (insn
);
4005 /* Do we need to emit a NOP? */
4007 || (mips_load_reg
!= (rtx
)0 && reg_mentioned_p (mips_load_reg
, pattern
))
4008 || (mips_load_reg2
!= (rtx
)0 && reg_mentioned_p (mips_load_reg2
, pattern
))
4009 || (mips_load_reg3
!= (rtx
)0 && reg_mentioned_p (mips_load_reg3
, pattern
))
4010 || (mips_load_reg4
!= (rtx
)0 && reg_mentioned_p (mips_load_reg4
, pattern
)))
4011 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
4014 dslots_load_filled
++;
4016 while (--dslots_number_nops
> 0)
4017 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
4019 mips_load_reg
= (rtx
)0;
4020 mips_load_reg2
= (rtx
)0;
4021 mips_load_reg3
= (rtx
)0;
4022 mips_load_reg4
= (rtx
)0;
4024 if (set_noreorder
&& --set_noreorder
== 0)
4025 fputs ("\t.set\treorder\n", asm_out_file
);
4030 enum rtx_code code
= GET_CODE (insn
);
4031 if (code
== JUMP_INSN
|| code
== CALL_INSN
)
4032 dslots_jump_total
++;
4037 /* Output at beginning of assembler file.
4038 If we are optimizing to use the global pointer, create a temporary
4039 file to hold all of the text stuff, and write it out to the end.
4040 This is needed because the MIPS assembler is evidently one pass,
4041 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata
4042 declaration when the code is processed, it generates a two
4043 instruction sequence. */
4046 mips_asm_file_start (stream
)
4049 ASM_OUTPUT_SOURCE_FILENAME (stream
, main_input_filename
);
4051 /* Versions of the MIPS assembler before 2.20 generate errors
4052 if a branch inside of a .set noreorder section jumps to a
4053 label outside of the .set noreorder section. Revision 2.20
4054 just set nobopt silently rather than fixing the bug. */
4056 if (TARGET_MIPS_AS
&& optimize
&& flag_delayed_branch
)
4057 fprintf (stream
, "\t.set\tnobopt\n");
4059 /* Generate the pseudo ops that System V.4 wants. */
4060 #ifndef ABICALLS_ASM_OP
4061 #define ABICALLS_ASM_OP ".abicalls"
4063 if (TARGET_ABICALLS
)
4064 /* ??? but do not want this (or want pic0) if -non-shared? */
4065 fprintf (stream
, "\t%s\n", ABICALLS_ASM_OP
);
4067 /* This code exists so that we can put all externs before all symbol
4068 references. This is necessary for the assembler's global pointer
4069 optimizations to work. */
4070 /* ??? Current versions of gas do not require that externs occur before
4071 symbol references. This means that this code is unnecessary when
4072 gas is being used. This gas feature hasn't been well tested as yet
4076 asm_out_data_file
= stream
;
4077 asm_out_text_file
= make_temp_file ();
4080 asm_out_data_file
= asm_out_text_file
= stream
;
4082 print_options (stream
);
4086 /* If we are optimizing the global pointer, emit the text section now
4087 and any small externs which did not have .comm, etc that are
4088 needed. Also, give a warning if the data area is more than 32K and
4089 -pic because 3 instructions are needed to reference the data
4093 mips_asm_file_end (file
)
4098 struct extern_list
*p
;
4102 HALF_PIC_FINISH (file
);
4109 for (p
= extern_head
; p
!= 0; p
= p
->next
)
4111 name_tree
= get_identifier (p
->name
);
4113 /* Positively ensure only one .extern for any given symbol. */
4114 if (! TREE_ASM_WRITTEN (name_tree
))
4116 TREE_ASM_WRITTEN (name_tree
) = 1;
4117 fputs ("\t.extern\t", file
);
4118 assemble_name (file
, p
->name
);
4119 fprintf (file
, ", %d\n", p
->size
);
4123 fprintf (file
, "\n\t.text\n");
4124 rewind (asm_out_text_file
);
4125 if (ferror (asm_out_text_file
))
4126 fatal_io_error (temp_filename
);
4128 while ((len
= fread (buffer
, 1, sizeof (buffer
), asm_out_text_file
)) > 0)
4129 if (fwrite (buffer
, 1, len
, file
) != len
)
4130 pfatal_with_name (asm_file_name
);
4133 pfatal_with_name (temp_filename
);
4135 if (fclose (asm_out_text_file
) != 0)
4136 pfatal_with_name (temp_filename
);
4139 unlink (temp_filename
);
4145 /* Emit either a label, .comm, or .lcomm directive, and mark
4146 that the symbol is used, so that we don't emit an .extern
4147 for it in mips_asm_file_end. */
4150 mips_declare_object (stream
, name
, init_string
, final_string
, size
)
4157 fputs (init_string
, stream
); /* "", "\t.comm\t", or "\t.lcomm\t" */
4158 assemble_name (stream
, name
);
4159 fprintf (stream
, final_string
, size
); /* ":\n", ",%u\n", ",%u\n" */
4163 tree name_tree
= get_identifier (name
);
4164 TREE_ASM_WRITTEN (name_tree
) = 1;
4169 /* Output a double precision value to the assembler. If both the
4170 host and target are IEEE, emit the values in hex. */
4173 mips_output_double (stream
, value
)
4175 REAL_VALUE_TYPE value
;
4177 #ifdef REAL_VALUE_TO_TARGET_DOUBLE
4179 REAL_VALUE_TO_TARGET_DOUBLE (value
, value_long
);
4181 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n",
4182 value_long
[0], value
, value_long
[1]);
4184 fprintf (stream
, "\t.double\t%.20g\n", value
);
4189 /* Output a single precision value to the assembler. If both the
4190 host and target are IEEE, emit the values in hex. */
4193 mips_output_float (stream
, value
)
4195 REAL_VALUE_TYPE value
;
4197 #ifdef REAL_VALUE_TO_TARGET_SINGLE
4199 REAL_VALUE_TO_TARGET_SINGLE (value
, value_long
);
4201 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long
, value
);
4203 fprintf (stream
, "\t.float\t%.12g\n", value
);
4208 /* Return TRUE if any register used in the epilogue is used. This to insure
4209 any insn put into the epilogue delay slots is safe. */
4212 epilogue_reg_mentioned_p (insn
)
4217 register enum rtx_code code
;
4223 if (GET_CODE (insn
) == LABEL_REF
)
4226 code
= GET_CODE (insn
);
4230 regno
= REGNO (insn
);
4231 if (regno
== STACK_POINTER_REGNUM
)
4234 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
4237 if (!call_used_regs
[regno
])
4240 if (regno
!= MIPS_TEMP1_REGNUM
&& regno
!= MIPS_TEMP2_REGNUM
)
4243 if (!current_frame_info
.initialized
)
4244 compute_frame_size (get_frame_size ());
4246 return (current_frame_info
.total_size
>= 32768);
4256 fmt
= GET_RTX_FORMAT (code
);
4257 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4262 for (j
= XVECLEN (insn
, i
) - 1; j
>= 0; j
--)
4263 if (epilogue_reg_mentioned_p (XVECEXP (insn
, i
, j
)))
4266 else if (fmt
[i
] == 'e' && epilogue_reg_mentioned_p (XEXP (insn
, i
)))
4274 /* Return the bytes needed to compute the frame pointer from the current
4277 Mips stack frames look like:
4279 Before call After call
4280 +-----------------------+ +-----------------------+
4283 | caller's temps. | | caller's temps. |
4285 +-----------------------+ +-----------------------+
4287 | arguments on stack. | | arguments on stack. |
4289 +-----------------------+ +-----------------------+
4290 | 4 words to save | | 4 words to save |
4291 | arguments passed | | arguments passed |
4292 | in registers, even | | in registers, even |
4293 SP->| if not passed. | VFP->| if not passed. |
4294 +-----------------------+ +-----------------------+
4296 | fp register save |
4298 +-----------------------+
4300 | gp register save |
4302 +-----------------------+
4306 +-----------------------+
4308 | alloca allocations |
4310 +-----------------------+
4312 | GP save for V.4 abi |
4314 +-----------------------+
4316 | arguments on stack |
4318 +-----------------------+
4320 | arguments passed |
4321 | in registers, even |
4322 low SP->| if not passed. |
4323 memory +-----------------------+
4328 compute_frame_size (size
)
4329 int size
; /* # of var. bytes allocated */
4332 long total_size
; /* # bytes that the entire frame takes up */
4333 long var_size
; /* # bytes that variables take up */
4334 long args_size
; /* # bytes that outgoing arguments take up */
4335 long extra_size
; /* # extra bytes */
4336 long gp_reg_rounded
; /* # bytes needed to store gp after rounding */
4337 long gp_reg_size
; /* # bytes needed to store gp regs */
4338 long fp_reg_size
; /* # bytes needed to store fp regs */
4339 long mask
; /* mask of saved gp registers */
4340 long fmask
; /* mask of saved fp registers */
4341 int fp_inc
; /* 1 or 2 depending on the size of fp regs */
4342 long fp_bits
; /* bitmask to use for each fp register */
4348 extra_size
= MIPS_STACK_ALIGN (((TARGET_ABICALLS
) ? UNITS_PER_WORD
: 0));
4349 var_size
= MIPS_STACK_ALIGN (size
);
4350 args_size
= MIPS_STACK_ALIGN (current_function_outgoing_args_size
);
4352 /* The MIPS 3.0 linker does not like functions that dynamically
4353 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
4354 looks like we are trying to create a second frame pointer to the
4355 function, so allocate some stack space to make it happy. */
4357 if (args_size
== 0 && current_function_calls_alloca
)
4358 args_size
= 4*UNITS_PER_WORD
;
4360 total_size
= var_size
+ args_size
+ extra_size
;
4362 /* Calculate space needed for gp registers. */
4363 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
4365 if (MUST_SAVE_REGISTER (regno
))
4367 gp_reg_size
+= UNITS_PER_WORD
;
4368 mask
|= 1L << (regno
- GP_REG_FIRST
);
4372 /* Calculate space needed for fp registers. */
4384 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
+= fp_inc
)
4386 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
4388 fp_reg_size
+= fp_inc
* UNITS_PER_FPREG
;
4389 fmask
|= fp_bits
<< (regno
- FP_REG_FIRST
);
4393 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
4394 total_size
+= gp_reg_rounded
+ fp_reg_size
;
4396 if (total_size
== extra_size
)
4397 total_size
= extra_size
= 0;
4398 else if (TARGET_ABICALLS
)
4400 /* Add the context-pointer to the saved registers. */
4401 gp_reg_size
+= UNITS_PER_WORD
;
4402 mask
|= 1L << (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
);
4403 total_size
-= gp_reg_rounded
;
4404 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
4405 total_size
+= gp_reg_rounded
;
4408 /* Save other computed information. */
4409 current_frame_info
.total_size
= total_size
;
4410 current_frame_info
.var_size
= var_size
;
4411 current_frame_info
.args_size
= args_size
;
4412 current_frame_info
.extra_size
= extra_size
;
4413 current_frame_info
.gp_reg_size
= gp_reg_size
;
4414 current_frame_info
.fp_reg_size
= fp_reg_size
;
4415 current_frame_info
.mask
= mask
;
4416 current_frame_info
.fmask
= fmask
;
4417 current_frame_info
.initialized
= reload_completed
;
4418 current_frame_info
.num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
4419 current_frame_info
.num_fp
= fp_reg_size
/ (fp_inc
* UNITS_PER_FPREG
);
4423 unsigned long offset
= args_size
+ extra_size
+ var_size
4424 + gp_reg_size
- UNITS_PER_WORD
;
4425 current_frame_info
.gp_sp_offset
= offset
;
4426 current_frame_info
.gp_save_offset
= offset
- total_size
;
4430 current_frame_info
.gp_sp_offset
= 0;
4431 current_frame_info
.gp_save_offset
= 0;
4437 unsigned long offset
= (args_size
+ extra_size
+ var_size
4438 + gp_reg_rounded
+ fp_reg_size
4439 - fp_inc
* UNITS_PER_FPREG
);
4440 current_frame_info
.fp_sp_offset
= offset
;
4441 current_frame_info
.fp_save_offset
= offset
- total_size
+ UNITS_PER_WORD
;
4445 current_frame_info
.fp_sp_offset
= 0;
4446 current_frame_info
.fp_save_offset
= 0;
4449 /* Ok, we're done. */
4454 /* Common code to emit the insns (or to write the instructions to a file)
4455 to save/restore registers.
4457 Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg)
4458 is not modified within save_restore_insns. */
4460 #define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0)
4463 save_restore_insns (store_p
, large_reg
, large_offset
, file
)
4464 int store_p
; /* true if this is prologue */
4465 rtx large_reg
; /* register holding large offset constant or NULL */
4466 long large_offset
; /* large constant offset value */
4467 FILE *file
; /* file to write instructions to instead of making RTL */
4469 long mask
= current_frame_info
.mask
;
4470 long fmask
= current_frame_info
.fmask
;
4478 if (frame_pointer_needed
&& !BITSET_P (mask
, FRAME_POINTER_REGNUM
- GP_REG_FIRST
))
4481 if (mask
== 0 && fmask
== 0)
4484 /* Save registers starting from high to low. The debuggers prefer
4485 at least the return register be stored at func+4, and also it
4486 allows us not to need a nop in the epilog if at least one
4487 register is reloaded in addition to return address. */
4489 /* Save GP registers if needed. */
4492 /* Pick which pointer to use as a base register. For small
4493 frames, just use the stack pointer. Otherwise, use a
4494 temporary register. Save 2 cycles if the save area is near
4495 the end of a large frame, by reusing the constant created in
4496 the prologue/epilogue to adjust the stack frame. */
4498 gp_offset
= current_frame_info
.gp_sp_offset
;
4499 end_offset
= gp_offset
- (current_frame_info
.gp_reg_size
- UNITS_PER_WORD
);
4501 if (gp_offset
< 0 || end_offset
< 0)
4502 fatal ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
4503 gp_offset
, end_offset
);
4505 else if (gp_offset
< 32768)
4507 base_reg_rtx
= stack_pointer_rtx
;
4511 else if (large_reg
!= (rtx
)0
4512 && (((unsigned long)(large_offset
- gp_offset
)) < 32768)
4513 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4515 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4516 base_offset
= large_offset
;
4517 if (file
== (FILE *)0)
4520 emit_insn (gen_adddi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4522 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4525 fprintf (file
, "\t%s\t%s,%s,%s\n",
4526 TARGET_LONG64
? "daddu" : "addu",
4527 reg_names
[MIPS_TEMP2_REGNUM
],
4528 reg_names
[REGNO (large_reg
)],
4529 reg_names
[STACK_POINTER_REGNUM
]);
4534 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4535 base_offset
= gp_offset
;
4536 if (file
== (FILE *)0)
4538 emit_move_insn (base_reg_rtx
, GEN_INT (gp_offset
));
4540 emit_insn (gen_adddi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4542 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4545 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n",
4546 reg_names
[MIPS_TEMP2_REGNUM
],
4549 TARGET_LONG64
? "daddu" : "addu",
4550 reg_names
[MIPS_TEMP2_REGNUM
],
4551 reg_names
[MIPS_TEMP2_REGNUM
],
4552 reg_names
[STACK_POINTER_REGNUM
]);
4555 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
4557 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
4559 if (file
== (FILE *)0)
4561 rtx reg_rtx
= gen_rtx (REG
, word_mode
, regno
);
4562 rtx mem_rtx
= gen_rtx (MEM
, word_mode
,
4563 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4564 GEN_INT (gp_offset
- base_offset
)));
4567 emit_move_insn (mem_rtx
, reg_rtx
);
4568 else if (!TARGET_ABICALLS
4569 || regno
!= (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
))
4570 emit_move_insn (reg_rtx
, mem_rtx
);
4574 if (store_p
|| !TARGET_ABICALLS
4575 || regno
!= (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
))
4576 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4578 ? (store_p
) ? "sd" : "ld"
4579 : (store_p
) ? "sw" : "lw"),
4581 gp_offset
- base_offset
,
4582 reg_names
[REGNO(base_reg_rtx
)]);
4585 gp_offset
-= UNITS_PER_WORD
;
4591 base_reg_rtx
= (rtx
)0; /* Make sure these are initialzed */
4595 /* Save floating point registers if needed. */
4598 int fp_inc
= (TARGET_FLOAT64
) ? 1 : 2;
4599 int fp_size
= fp_inc
* UNITS_PER_FPREG
;
4601 /* Pick which pointer to use as a base register. */
4602 fp_offset
= current_frame_info
.fp_sp_offset
;
4603 end_offset
= fp_offset
- (current_frame_info
.fp_reg_size
- fp_size
);
4605 if (fp_offset
< 0 || end_offset
< 0)
4606 fatal ("fp_offset (%ld) or end_offset (%ld) is less than zero.",
4607 fp_offset
, end_offset
);
4609 else if (fp_offset
< 32768)
4611 base_reg_rtx
= stack_pointer_rtx
;
4615 else if (base_reg_rtx
!= (rtx
)0
4616 && (((unsigned long)(base_offset
- fp_offset
)) < 32768)
4617 && (((unsigned long)(base_offset
- end_offset
)) < 32768))
4619 ; /* already set up for gp registers above */
4622 else if (large_reg
!= (rtx
)0
4623 && (((unsigned long)(large_offset
- fp_offset
)) < 32768)
4624 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4626 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4627 base_offset
= large_offset
;
4628 if (file
== (FILE *)0)
4631 emit_insn (gen_adddi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4633 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4636 fprintf (file
, "\t%s\t%s,%s,%s\n",
4637 TARGET_LONG64
? "daddu" : "addu",
4638 reg_names
[MIPS_TEMP2_REGNUM
],
4639 reg_names
[REGNO (large_reg
)],
4640 reg_names
[STACK_POINTER_REGNUM
]);
4645 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4646 base_offset
= fp_offset
;
4647 if (file
== (FILE *)0)
4649 emit_move_insn (base_reg_rtx
, GEN_INT (fp_offset
));
4651 emit_insn (gen_adddi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4653 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4656 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n",
4657 reg_names
[MIPS_TEMP2_REGNUM
],
4660 TARGET_LONG64
? "daddu" : "addu",
4661 reg_names
[MIPS_TEMP2_REGNUM
],
4662 reg_names
[MIPS_TEMP2_REGNUM
],
4663 reg_names
[STACK_POINTER_REGNUM
]);
4666 for (regno
= FP_REG_LAST
-1; regno
>= FP_REG_FIRST
; regno
-= fp_inc
)
4668 if (BITSET_P (fmask
, regno
- FP_REG_FIRST
))
4670 if (file
== (FILE *)0)
4672 rtx reg_rtx
= gen_rtx (REG
, DFmode
, regno
);
4673 rtx mem_rtx
= gen_rtx (MEM
, DFmode
,
4674 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4675 GEN_INT (fp_offset
- base_offset
)));
4678 emit_move_insn (mem_rtx
, reg_rtx
);
4680 emit_move_insn (reg_rtx
, mem_rtx
);
4683 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4684 (store_p
) ? "s.d" : "l.d",
4686 fp_offset
- base_offset
,
4687 reg_names
[REGNO(base_reg_rtx
)]);
4690 fp_offset
-= fp_size
;
4697 /* Set up the stack and frame (if desired) for the function. */
4700 function_prologue (file
, size
)
4704 long tsize
= current_frame_info
.total_size
;
4706 ASM_OUTPUT_SOURCE_FILENAME (file
, DECL_SOURCE_FILE (current_function_decl
));
4708 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
4709 ASM_OUTPUT_SOURCE_LINE (file
, DECL_SOURCE_LINE (current_function_decl
));
4711 inside_function
= 1;
4712 fputs ("\t.ent\t", file
);
4713 assemble_name (file
, current_function_name
);
4716 assemble_name (file
, current_function_name
);
4717 fputs (":\n", file
);
4719 fprintf (file
, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args= %d, extra= %d\n",
4720 reg_names
[ (frame_pointer_needed
) ? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
],
4722 reg_names
[31 + GP_REG_FIRST
],
4723 current_frame_info
.var_size
,
4724 current_frame_info
.num_gp
,
4725 current_frame_info
.num_fp
,
4726 current_function_outgoing_args_size
,
4727 current_frame_info
.extra_size
);
4729 fprintf (file
, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n",
4730 current_frame_info
.mask
,
4731 current_frame_info
.gp_save_offset
,
4732 current_frame_info
.fmask
,
4733 current_frame_info
.fp_save_offset
);
4735 if (TARGET_ABICALLS
)
4737 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4739 fprintf (file
, "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
4740 reg_names
[PIC_FUNCTION_ADDR_REGNUM
]);
4743 fprintf (file
, "\t%s\t%s,%s,%d\n",
4744 (TARGET_LONG64
? "dsubu" : "subu"),
4745 sp_str
, sp_str
, tsize
);
4746 fprintf (file
, "\t.cprestore %d\n", current_frame_info
.args_size
);
4752 /* Expand the prologue into a bunch of separate insns. */
4755 mips_expand_prologue ()
4759 rtx tmp_rtx
= (rtx
)0;
4760 char *arg_name
= (char *)0;
4761 tree fndecl
= current_function_decl
;
4762 tree fntype
= TREE_TYPE (fndecl
);
4763 tree fnargs
= (TREE_CODE (fntype
) != METHOD_TYPE
)
4764 ? DECL_ARGUMENTS (fndecl
)
4770 CUMULATIVE_ARGS args_so_far
;
4772 /* If struct value address is treated as the first argument, make it so. */
4773 if (aggregate_value_p (DECL_RESULT (fndecl
))
4774 && ! current_function_returns_pcc_struct
4775 && struct_value_incoming_rtx
== 0)
4777 tree type
= build_pointer_type (fntype
);
4778 tree function_result_decl
= build_decl (PARM_DECL
, NULL_TREE
, type
);
4779 DECL_ARG_TYPE (function_result_decl
) = type
;
4780 TREE_CHAIN (function_result_decl
) = fnargs
;
4781 fnargs
= function_result_decl
;
4784 /* Determine the last argument, and get its name. */
4786 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, (rtx
)0);
4787 regno
= GP_ARG_FIRST
;
4789 for (cur_arg
= fnargs
; cur_arg
!= (tree
)0; cur_arg
= next_arg
)
4791 tree type
= DECL_ARG_TYPE (cur_arg
);
4792 enum machine_mode passed_mode
= TYPE_MODE (type
);
4793 rtx entry_parm
= FUNCTION_ARG (args_so_far
,
4795 DECL_ARG_TYPE (cur_arg
),
4802 /* passed in a register, so will get homed automatically */
4803 if (GET_MODE (entry_parm
) == BLKmode
)
4804 words
= (int_size_in_bytes (type
) + 3) / 4;
4806 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
4808 regno
= REGNO (entry_parm
) + words
- 1;
4812 regno
= GP_ARG_LAST
+1;
4816 FUNCTION_ARG_ADVANCE (args_so_far
,
4818 DECL_ARG_TYPE (cur_arg
),
4821 next_arg
= TREE_CHAIN (cur_arg
);
4822 if (next_arg
== (tree
)0)
4824 if (DECL_NAME (cur_arg
))
4825 arg_name
= IDENTIFIER_POINTER (DECL_NAME (cur_arg
));
4831 /* In order to pass small structures by value in registers
4832 compatibly with the MIPS compiler, we need to shift the value
4833 into the high part of the register. Function_arg has encoded a
4834 PARALLEL rtx, holding a vector of adjustments to be made as the
4835 next_arg_reg variable, so we split up the insns, and emit them
4838 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
4839 if (next_arg_reg
!= (rtx
)0 && GET_CODE (next_arg_reg
) == PARALLEL
)
4841 rtvec adjust
= XVEC (next_arg_reg
, 0);
4842 int num
= GET_NUM_ELEM (adjust
);
4844 for (i
= 0; i
< num
; i
++)
4846 rtx pattern
= RTVEC_ELT (adjust
, i
);
4847 if (GET_CODE (pattern
) != SET
4848 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
4849 abort_with_insn (pattern
, "Insn is not a shift");
4851 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
4852 emit_insn (pattern
);
4856 tsize
= compute_frame_size (get_frame_size ());
4858 /* If this function is a varargs function, store any registers that
4859 would normally hold arguments ($4 - $7) on the stack. */
4860 if ((TYPE_ARG_TYPES (fntype
) != 0
4861 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
))) != void_type_node
))
4862 || (arg_name
!= (char *)0
4863 && ((arg_name
[0] == '_' && strcmp (arg_name
, "__builtin_va_alist") == 0)
4864 || (arg_name
[0] == 'v' && strcmp (arg_name
, "va_alist") == 0))))
4866 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
4867 rtx ptr
= stack_pointer_rtx
;
4869 /* If we are doing svr4-abi, sp has already been decremented by tsize. */
4870 if (TARGET_ABICALLS
)
4873 for (; regno
<= GP_ARG_LAST
; regno
++)
4876 ptr
= gen_rtx (PLUS
, Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
4877 emit_move_insn (gen_rtx (MEM
, word_mode
, ptr
),
4878 gen_rtx (REG
, word_mode
, regno
));
4879 offset
+= UNITS_PER_WORD
;
4885 rtx tsize_rtx
= GEN_INT (tsize
);
4887 /* If we are doing svr4-abi, sp move is done by function_prologue. */
4888 if (!TARGET_ABICALLS
)
4892 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
4893 emit_move_insn (tmp_rtx
, tsize_rtx
);
4894 tsize_rtx
= tmp_rtx
;
4898 emit_insn (gen_subdi3 (stack_pointer_rtx
, stack_pointer_rtx
,
4901 emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
4905 save_restore_insns (TRUE
, tmp_rtx
, tsize
, (FILE *)0);
4907 if (frame_pointer_needed
)
4910 emit_insn (gen_movdi (frame_pointer_rtx
, stack_pointer_rtx
));
4912 emit_insn (gen_movsi (frame_pointer_rtx
, stack_pointer_rtx
));
4916 /* If we are profiling, make sure no instructions are scheduled before
4917 the call to mcount. */
4919 if (profile_flag
|| profile_block_flag
)
4920 emit_insn (gen_blockage ());
4924 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */
4926 #define RA_MASK ((long) 0x80000000) /* 1 << 31 */
4927 #define PIC_OFFSET_TABLE_MASK (1 << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))
4930 function_epilogue (file
, size
)
4935 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4936 char *t1_str
= reg_names
[MIPS_TEMP1_REGNUM
];
4937 rtx epilogue_delay
= current_function_epilogue_delay_list
;
4938 int noreorder
= !TARGET_MIPS_AS
|| (epilogue_delay
!= 0);
4939 int noepilogue
= FALSE
;
4940 int load_nop
= FALSE
;
4942 rtx tmp_rtx
= (rtx
)0;
4946 /* The epilogue does not depend on any registers, but the stack
4947 registers, so we assume that if we have 1 pending nop, it can be
4948 ignored, and 2 it must be filled (2 nops occur for integer
4949 multiply and divide). */
4951 if (dslots_number_nops
> 0)
4953 if (dslots_number_nops
== 1)
4955 dslots_number_nops
= 0;
4956 dslots_load_filled
++;
4960 while (--dslots_number_nops
> 0)
4961 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
4964 if (set_noreorder
> 0 && --set_noreorder
== 0)
4965 fputs ("\t.set\treorder\n", file
);
4971 fputs ("\t.set\tat\n", file
);
4972 error ("internal gcc error: .set noat left on in epilogue");
4975 if (set_nomacro
!= 0)
4978 fputs ("\t.set\tmacro\n", file
);
4979 error ("internal gcc error: .set nomacro left on in epilogue");
4982 if (set_noreorder
!= 0)
4985 fputs ("\t.set\treorder\n", file
);
4986 error ("internal gcc error: .set noreorder left on in epilogue");
4989 if (set_volatile
!= 0)
4992 fprintf (file
, "\t%s.set\tnovolatile\n", (TARGET_MIPS_AS
) ? "" : "#");
4993 error ("internal gcc error: .set volatile left on in epilogue");
4996 size
= MIPS_STACK_ALIGN (size
);
4997 tsize
= (!current_frame_info
.initialized
)
4998 ? compute_frame_size (size
)
4999 : current_frame_info
.total_size
;
5001 if (tsize
== 0 && epilogue_delay
== 0)
5003 rtx insn
= get_last_insn ();
5005 /* If the last insn was a BARRIER, we don't have to write any code
5006 because a jump (aka return) was put there. */
5007 if (GET_CODE (insn
) == NOTE
)
5008 insn
= prev_nonnote_insn (insn
);
5009 if (insn
&& GET_CODE (insn
) == BARRIER
)
5017 /* In the reload sequence, we don't need to fill the load delay
5018 slots for most of the loads, also see if we can fill the final
5019 delay slot if not otherwise filled by the reload sequence. */
5022 fprintf (file
, "\t.set\tnoreorder\n");
5026 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str
, (long)tsize
, (long)tsize
);
5027 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
5030 if (frame_pointer_needed
)
5031 fprintf (file
, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
5032 sp_str
, reg_names
[FRAME_POINTER_REGNUM
]);
5034 save_restore_insns (FALSE
, tmp_rtx
, tsize
, file
);
5036 load_only_r31
= (((current_frame_info
.mask
5037 & ~ (TARGET_ABICALLS
? PIC_OFFSET_TABLE_MASK
: 0))
5039 && current_frame_info
.fmask
== 0);
5043 /* If the only register saved is the return address, we need a
5044 nop, unless we have an instruction to put into it. Otherwise
5045 we don't since reloading multiple registers doesn't reference
5046 the register being loaded. */
5051 final_scan_insn (XEXP (epilogue_delay
, 0),
5055 1); /* nopeepholes */
5058 fprintf (file
, "\tnop\n");
5063 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
5066 fprintf (file
, "\t%s\t%s,%s,%s\n",
5067 TARGET_LONG64
? "daddu" : "addu",
5068 sp_str
, sp_str
, t1_str
);
5071 fprintf (file
, "\t%s\t%s,%s,%d\n",
5072 TARGET_LONG64
? "daddu" : "addu",
5073 sp_str
, sp_str
, tsize
);
5075 else if (!load_only_r31
&& epilogue_delay
!= 0)
5076 final_scan_insn (XEXP (epilogue_delay
, 0),
5080 1); /* nopeepholes */
5082 fprintf (file
, "\t.set\treorder\n");
5088 fprintf (file
, "\t%s\t%s,%s,%s\n",
5089 TARGET_LONG64
? "daddu" : "addu",
5090 sp_str
, sp_str
, t1_str
);
5093 fprintf (file
, "\t%s\t%s,%s,%d\n",
5094 TARGET_LONG64
? "daddu" : "addu",
5095 sp_str
, sp_str
, tsize
);
5097 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
5101 fputs ("\t.end\t", file
);
5102 assemble_name (file
, current_function_name
);
5107 int num_gp_regs
= current_frame_info
.gp_reg_size
/ 4;
5108 int num_fp_regs
= current_frame_info
.fp_reg_size
/ 8;
5109 int num_regs
= num_gp_regs
+ num_fp_regs
;
5110 char *name
= current_function_name
;
5115 dslots_load_total
+= num_regs
;
5118 dslots_jump_total
++;
5122 dslots_load_filled
+= num_regs
;
5124 /* If the only register saved is the return register, we
5125 can't fill this register's delay slot. */
5127 if (load_only_r31
&& epilogue_delay
== 0)
5128 dslots_load_filled
--;
5130 if (tsize
> 0 || (!load_only_r31
&& epilogue_delay
!= 0))
5131 dslots_jump_filled
++;
5135 "%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d",
5137 (frame_pointer_needed
) ? 'y' : 'n',
5138 ((current_frame_info
.mask
& RA_MASK
) != 0) ? 'n' : 'y',
5139 (current_function_calls_alloca
) ? 'y' : 'n',
5140 (current_function_calls_setjmp
) ? 'y' : 'n',
5141 (long)current_frame_info
.total_size
,
5142 (long)current_function_outgoing_args_size
,
5143 num_gp_regs
, num_fp_regs
,
5144 dslots_load_total
, dslots_load_filled
,
5145 dslots_jump_total
, dslots_jump_filled
,
5146 num_refs
[0], num_refs
[1], num_refs
[2]);
5148 if (HALF_PIC_NUMBER_PTRS
> prev_half_pic_ptrs
)
5150 fprintf (stderr
, " half-pic=%3d", HALF_PIC_NUMBER_PTRS
- prev_half_pic_ptrs
);
5151 prev_half_pic_ptrs
= HALF_PIC_NUMBER_PTRS
;
5154 if (HALF_PIC_NUMBER_REFS
> prev_half_pic_refs
)
5156 fprintf (stderr
, " pic-ref=%3d", HALF_PIC_NUMBER_REFS
- prev_half_pic_refs
);
5157 prev_half_pic_refs
= HALF_PIC_NUMBER_REFS
;
5160 fputc ('\n', stderr
);
5163 /* Reset state info for each function. */
5164 inside_function
= FALSE
;
5165 ignore_line_number
= FALSE
;
5166 dslots_load_total
= 0;
5167 dslots_jump_total
= 0;
5168 dslots_load_filled
= 0;
5169 dslots_jump_filled
= 0;
5173 mips_load_reg
= (rtx
)0;
5174 mips_load_reg2
= (rtx
)0;
5175 current_frame_info
= zero_frame_info
;
5177 /* Restore the output file if optimizing the GP (optimizing the GP causes
5178 the text to be diverted to a tempfile, so that data decls come before
5179 references to the data). */
5182 asm_out_file
= asm_out_data_file
;
5186 /* Expand the epilogue into a bunch of separate insns. */
5189 mips_expand_epilogue ()
5191 long tsize
= current_frame_info
.total_size
;
5192 rtx tsize_rtx
= GEN_INT (tsize
);
5193 rtx tmp_rtx
= (rtx
)0;
5197 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
5198 emit_move_insn (tmp_rtx
, tsize_rtx
);
5199 tsize_rtx
= tmp_rtx
;
5204 if (frame_pointer_needed
)
5207 emit_insn (gen_movdi (stack_pointer_rtx
, frame_pointer_rtx
));
5209 emit_insn (gen_movsi (stack_pointer_rtx
, frame_pointer_rtx
));
5212 save_restore_insns (FALSE
, tmp_rtx
, tsize
, (FILE *)0);
5215 emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
5218 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
5222 emit_jump_insn (gen_return_internal (gen_rtx (REG
, Pmode
, GP_REG_FIRST
+31)));
5226 /* Define the number of delay slots needed for the function epilogue.
5228 On the mips, we need a slot if either no stack has been allocated,
5229 or the only register saved is the return register. */
5232 mips_epilogue_delay_slots ()
5234 if (!current_frame_info
.initialized
)
5235 (void) compute_frame_size (get_frame_size ());
5237 if (current_frame_info
.total_size
== 0)
5240 if (current_frame_info
.mask
== RA_MASK
&& current_frame_info
.fmask
== 0)
5247 /* Return true if this function is known to have a null epilogue.
5248 This allows the optimizer to omit jumps to jumps if no stack
5252 simple_epilogue_p ()
5254 if (!reload_completed
)
5257 if (current_frame_info
.initialized
)
5258 return current_frame_info
.total_size
== 0;
5260 return (compute_frame_size (get_frame_size ())) == 0;