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 giving truth value on whether or not a given hard register
208 can support a given mode. */
209 char mips_hard_regno_mode_ok
[(int)MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
211 /* Current frame information calculated by compute_frame_size. */
212 struct mips_frame_info current_frame_info
;
214 /* Zero structure to initialize current_frame_info. */
215 struct mips_frame_info zero_frame_info
;
217 /* Temporary filename used to buffer .text until end of program
219 static char *temp_filename
;
221 /* Pseudo-reg holding the address of the current function when
222 generating embedded PIC code. Created by LEGITIMIZE_ADDRESS, used
223 by mips_finalize_pic if it was created. */
224 rtx embedded_pic_fnaddr_rtx
;
226 /* List of all MIPS punctuation characters used by print_operand. */
227 char mips_print_operand_punct
[256];
229 /* Map GCC register number to debugger register number. */
230 int mips_dbx_regno
[FIRST_PSEUDO_REGISTER
];
232 /* Buffer to use to enclose a load/store operation with %{ %} to
233 turn on .set volatile. */
234 static char volatile_buffer
[60];
236 /* Hardware names for the registers. If -mrnames is used, this
237 will be overwritten with mips_sw_reg_names. */
239 char mips_reg_names
[][8] =
241 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
242 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
243 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
244 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
245 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
246 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
247 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
248 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
252 /* Mips software names for the registers, used to overwrite the
253 mips_reg_names array. */
255 char mips_sw_reg_names
[][8] =
257 "$zero","$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3",
258 "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
259 "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7",
260 "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra",
261 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
262 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
263 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
264 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
268 /* Map hard register number to register class */
269 enum reg_class mips_regno_to_class
[] =
271 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
272 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
273 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
274 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
275 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
276 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
277 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
278 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
279 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
280 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
281 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
282 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
283 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
284 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
285 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
286 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
287 HI_REG
, LO_REG
, ST_REGS
290 /* Map register constraint character to register class. */
291 enum reg_class mips_char_to_class
[256] =
293 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
294 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
295 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
296 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
297 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
298 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
299 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
300 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
301 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
302 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
303 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
304 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
305 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
306 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
307 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
308 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
309 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
310 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
311 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
312 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
313 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
314 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
315 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
316 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
317 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
318 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
319 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
320 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
321 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
322 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
323 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
324 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
325 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
326 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
327 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
328 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
329 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
330 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
331 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
332 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
333 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
334 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
335 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
336 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
337 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
338 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
339 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
340 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
341 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
342 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
343 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
344 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
345 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
346 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
347 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
348 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
349 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
350 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
351 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
352 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
353 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
354 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
355 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
356 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
360 /* Return truth value of whether OP can be used as an operands
361 where a register or 16 bit unsigned integer is needed. */
364 uns_arith_operand (op
, mode
)
366 enum machine_mode mode
;
368 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT_UNSIGNED (op
))
371 return register_operand (op
, mode
);
374 /* Return truth value of whether OP can be used as an operands
375 where a 16 bit integer is needed */
378 arith_operand (op
, mode
)
380 enum machine_mode mode
;
382 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
))
385 return register_operand (op
, mode
);
388 /* Return truth value of whether OP can be used as an operand in a two
389 address arithmetic insn (such as set 123456,%o4) of mode MODE. */
392 arith32_operand (op
, mode
)
394 enum machine_mode mode
;
396 if (GET_CODE (op
) == CONST_INT
)
399 return register_operand (op
, mode
);
402 /* Return truth value of whether OP is a integer which fits in 16 bits */
407 enum machine_mode mode
;
409 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
412 /* Return truth value of whether OP is an integer which is too big to
413 be loaded with one instruction. */
418 enum machine_mode mode
;
422 if (GET_CODE (op
) != CONST_INT
)
426 if ((value
& ~0x0000ffff) == 0) /* ior reg,$r0,value */
429 if (((unsigned long)(value
+ 32768)) <= 32767) /* subu reg,$r0,value */
432 if ((value
& 0x0000ffff) == 0 /* lui reg,value>>16 */
433 && ((value
& ~2147483647) == 0 /* signed value */
434 || (value
& ~2147483647) == ~2147483647))
440 /* Return truth value of whether OP is a register or the constant 0. */
443 reg_or_0_operand (op
, mode
)
445 enum machine_mode mode
;
447 switch (GET_CODE (op
))
453 return (INTVAL (op
) == 0);
456 if (op
!= CONST0_RTX (mode
))
463 return register_operand (op
, mode
);
469 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
472 mips_const_double_ok (op
, mode
)
474 enum machine_mode mode
;
478 if (GET_CODE (op
) != CONST_DOUBLE
)
484 if (mode
!= SFmode
&& mode
!= DFmode
)
487 if (op
== CONST0_RTX (mode
))
490 REAL_VALUE_FROM_CONST_DOUBLE (d
, op
);
492 if (REAL_VALUE_ISNAN (d
))
495 if (REAL_VALUE_NEGATIVE (d
))
496 d
= REAL_VALUE_NEGATE (d
);
500 if (REAL_VALUES_LESS (d
, dfhigh
)
501 && REAL_VALUES_LESS (dflow
, d
))
506 if (REAL_VALUES_LESS (d
, sfhigh
)
507 && REAL_VALUES_LESS (sflow
, d
))
514 /* Return truth value if a memory operand fits in a single instruction
515 (ie, register + small offset). */
518 simple_memory_operand (op
, mode
)
520 enum machine_mode mode
;
522 rtx addr
, plus0
, plus1
;
524 /* Eliminate non-memory operations */
525 if (GET_CODE (op
) != MEM
)
528 /* dword operations really put out 2 instructions, so eliminate them. */
529 if (GET_MODE_SIZE (GET_MODE (op
)) > UNITS_PER_WORD
)
532 /* Decode the address now. */
534 switch (GET_CODE (addr
))
543 return SMALL_INT (op
);
546 plus0
= XEXP (addr
, 0);
547 plus1
= XEXP (addr
, 1);
548 if (GET_CODE (plus0
) == REG
549 && GET_CODE (plus1
) == CONST_INT
550 && SMALL_INT (plus1
))
553 else if (GET_CODE (plus1
) == REG
554 && GET_CODE (plus0
) == CONST_INT
555 && SMALL_INT (plus0
))
562 /* We used to allow small symbol refs here (ie, stuff in .sdata
563 or .sbss), but this causes some bugs in G++. Also, it won't
564 interfere if the MIPS linker rewrites the store instruction
565 because the function is PIC. */
567 case LABEL_REF
: /* never gp relative */
571 /* If -G 0, we can never have a GP relative memory operation.
572 Also, save some time if not optimizing. */
577 rtx offset
= const0_rtx
;
578 addr
= eliminate_constant_term (XEXP (addr
, 0), &offset
);
579 if (GET_CODE (op
) != SYMBOL_REF
)
582 /* let's be paranoid.... */
583 if (! SMALL_INT (offset
))
589 return SYMBOL_REF_FLAG (addr
);
596 /* Return true if the code of this rtx pattern is EQ or NE. */
599 equality_op (op
, mode
)
601 enum machine_mode mode
;
603 if (mode
!= GET_MODE (op
))
606 return (GET_CODE (op
) == EQ
|| GET_CODE (op
) == NE
);
609 /* Return true if the code is a relational operations (EQ, LE, etc.) */
614 enum machine_mode mode
;
616 if (mode
!= GET_MODE (op
))
619 return (GET_RTX_CLASS (GET_CODE (op
)) == '<');
622 /* Return true if the operand is either the PC or a label_ref. */
625 pc_or_label_operand (op
, mode
)
627 enum machine_mode mode
;
632 if (GET_CODE (op
) == LABEL_REF
)
638 /* Test for a valid operand for a call instruction.
639 Don't allow the arg pointer register or virtual regs
640 since they may change into reg + const, which the patterns
644 call_insn_operand (op
, mode
)
646 enum machine_mode mode
;
648 if (GET_CODE (op
) == MEM
649 && (CONSTANT_ADDRESS_P (XEXP (op
, 0))
650 || (GET_CODE (XEXP (op
, 0)) == REG
651 && XEXP (op
, 0) != arg_pointer_rtx
652 && !(REGNO (XEXP (op
, 0)) >= FIRST_PSEUDO_REGISTER
653 && REGNO (XEXP (op
, 0)) <= LAST_VIRTUAL_REGISTER
))))
658 /* Returns an operand string for the given instruction's delay slot,
659 after updating filled delay slot statistics.
661 We assume that operands[0] is the target register that is set.
663 In order to check the next insn, most of this functionality is moved
664 to FINAL_PRESCAN_INSN, and we just set the global variables that
667 /* ??? This function no longer does anything useful, because final_prescan_insn
668 now will never emit a nop. */
671 mips_fill_delay_slot (ret
, type
, operands
, cur_insn
)
672 char *ret
; /* normal string to return */
673 enum delay_type type
; /* type of delay */
674 rtx operands
[]; /* operands to use */
675 rtx cur_insn
; /* current insn */
677 register rtx set_reg
;
678 register enum machine_mode mode
;
679 register rtx next_insn
= (cur_insn
) ? NEXT_INSN (cur_insn
) : (rtx
)0;
680 register int num_nops
;
682 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
685 else if (type
== DELAY_HILO
)
691 /* Make sure that we don't put nop's after labels. */
692 next_insn
= NEXT_INSN (cur_insn
);
693 while (next_insn
!= (rtx
)0 && GET_CODE (next_insn
) == NOTE
)
694 next_insn
= NEXT_INSN (next_insn
);
696 dslots_load_total
+= num_nops
;
697 if (TARGET_DEBUG_F_MODE
699 || type
== DELAY_NONE
700 || operands
== (rtx
*)0
701 || cur_insn
== (rtx
)0
702 || next_insn
== (rtx
)0
703 || GET_CODE (next_insn
) == CODE_LABEL
704 || (set_reg
= operands
[0]) == (rtx
)0)
706 dslots_number_nops
= 0;
707 mips_load_reg
= (rtx
)0;
708 mips_load_reg2
= (rtx
)0;
709 mips_load_reg3
= (rtx
)0;
710 mips_load_reg4
= (rtx
)0;
714 set_reg
= operands
[0];
715 if (set_reg
== (rtx
)0)
718 while (GET_CODE (set_reg
) == SUBREG
)
719 set_reg
= SUBREG_REG (set_reg
);
721 mode
= GET_MODE (set_reg
);
722 dslots_number_nops
= num_nops
;
723 mips_load_reg
= set_reg
;
724 if (GET_MODE_SIZE (mode
)
725 > (FP_REG_P (set_reg
) ? UNITS_PER_FPREG
: UNITS_PER_WORD
))
726 mips_load_reg2
= gen_rtx (REG
, SImode
, REGNO (set_reg
) + 1);
730 if (type
== DELAY_HILO
)
732 mips_load_reg3
= gen_rtx (REG
, SImode
, MD_REG_FIRST
);
733 mips_load_reg4
= gen_rtx (REG
, SImode
, MD_REG_FIRST
+1);
745 /* Determine whether a memory reference takes one (based off of the GP pointer),
746 two (normal), or three (label + reg) instructions, and bump the appropriate
747 counter for -mstats. */
750 mips_count_memory_refs (op
, num
)
756 rtx addr
, plus0
, plus1
;
757 enum rtx_code code0
, code1
;
760 if (TARGET_DEBUG_B_MODE
)
762 fprintf (stderr
, "\n========== mips_count_memory_refs:\n");
766 /* Skip MEM if passed, otherwise handle movsi of address. */
767 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
769 /* Loop, going through the address RTL */
773 switch (GET_CODE (addr
))
783 plus0
= XEXP (addr
, 0);
784 plus1
= XEXP (addr
, 1);
785 code0
= GET_CODE (plus0
);
786 code1
= GET_CODE (plus1
);
796 if (code0
== CONST_INT
)
811 if (code1
== CONST_INT
)
818 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
825 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
835 n_words
= 2; /* always 2 words */
839 addr
= XEXP (addr
, 0);
844 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
853 n_words
+= additional
;
857 num_refs
[n_words
-1] += num
;
861 /* Return RTL for the offset from the current function to the
865 embedded_pic_offset (x
)
868 if (embedded_pic_fnaddr_rtx
== NULL
)
869 embedded_pic_fnaddr_rtx
= gen_reg_rtx (Pmode
);
870 return gen_rtx (CONST
, Pmode
,
871 gen_rtx (MINUS
, Pmode
, x
,
872 XEXP (DECL_RTL (current_function_decl
), 0)));
875 /* Return the appropriate instructions to move one operand to another. */
878 mips_move_1word (operands
, insn
, unsignedp
)
884 rtx op0
= operands
[0];
885 rtx op1
= operands
[1];
886 enum rtx_code code0
= GET_CODE (op0
);
887 enum rtx_code code1
= GET_CODE (op1
);
888 enum machine_mode mode
= GET_MODE (op0
);
889 int subreg_word0
= 0;
890 int subreg_word1
= 0;
891 enum delay_type delay
= DELAY_NONE
;
893 while (code0
== SUBREG
)
895 subreg_word0
+= SUBREG_WORD (op0
);
896 op0
= SUBREG_REG (op0
);
897 code0
= GET_CODE (op0
);
900 while (code1
== SUBREG
)
902 subreg_word1
+= SUBREG_WORD (op1
);
903 op1
= SUBREG_REG (op1
);
904 code1
= GET_CODE (op1
);
909 int regno0
= REGNO (op0
) + subreg_word0
;
913 int regno1
= REGNO (op1
) + subreg_word1
;
915 /* Just in case, don't do anything for assigning a register
916 to itself, unless we are filling a delay slot. */
917 if (regno0
== regno1
&& set_nomacro
== 0)
920 else if (GP_REG_P (regno0
))
922 if (GP_REG_P (regno1
))
925 else if (MD_REG_P (regno1
))
934 if (FP_REG_P (regno1
))
937 else if (regno1
== FPSW_REGNUM
)
938 ret
= "cfc1\t%0,$31";
942 else if (FP_REG_P (regno0
))
944 if (GP_REG_P (regno1
))
950 if (FP_REG_P (regno1
))
951 ret
= "mov.s\t%0,%1";
954 else if (MD_REG_P (regno0
))
956 if (GP_REG_P (regno1
))
963 else if (regno0
== FPSW_REGNUM
)
965 if (GP_REG_P (regno1
))
968 ret
= "ctc1\t%0,$31";
973 else if (code1
== MEM
)
978 mips_count_memory_refs (op1
, 1);
980 if (GP_REG_P (regno0
))
982 /* For loads, use the mode of the memory item, instead of the
983 target, so zero/sign extend can use this code as well. */
984 switch (GET_MODE (op1
))
992 ret
= ((unsignedp
&& TARGET_64BIT
)
997 ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1";
1000 ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1";
1005 else if (FP_REG_P (regno0
) && (mode
== SImode
|| mode
== SFmode
))
1008 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1010 int i
= strlen (ret
);
1011 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1014 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1015 ret
= volatile_buffer
;
1019 else if (code1
== CONST_INT
)
1021 if (INTVAL (op1
) == 0)
1023 if (GP_REG_P (regno0
))
1024 ret
= "move\t%0,%z1";
1026 else if (FP_REG_P (regno0
))
1029 ret
= "mtc1\t%z1,%0";
1033 else if (GP_REG_P (regno0
))
1034 ret
= (INTVAL (op1
) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1";
1037 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
1039 if (op1
== CONST0_RTX (SFmode
))
1041 if (GP_REG_P (regno0
))
1042 ret
= "move\t%0,%.";
1044 else if (FP_REG_P (regno0
))
1047 ret
= "mtc1\t%.,%0";
1054 ret
= "li.s\t%0,%1";
1058 else if (code1
== LABEL_REF
)
1061 mips_count_memory_refs (op1
, 1);
1066 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
1068 if (HALF_PIC_P () && CONSTANT_P (op1
) && HALF_PIC_ADDRESS_P (op1
))
1070 rtx offset
= const0_rtx
;
1072 if (GET_CODE (op1
) == CONST
)
1073 op1
= eliminate_constant_term (XEXP (op1
, 0), &offset
);
1075 if (GET_CODE (op1
) == SYMBOL_REF
)
1077 operands
[2] = HALF_PIC_PTR (op1
);
1080 mips_count_memory_refs (operands
[2], 1);
1082 if (INTVAL (offset
) == 0)
1085 ret
= (unsignedp
&& TARGET_64BIT
1091 dslots_load_total
++;
1092 operands
[3] = offset
;
1093 if (unsignedp
&& TARGET_64BIT
)
1094 ret
= (SMALL_INT (offset
))
1095 ? "lwu\t%0,%2%#\n\tadd\t%0,%0,%3"
1096 : "lwu\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1098 ret
= (SMALL_INT (offset
))
1099 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"
1100 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1107 mips_count_memory_refs (op1
, 1);
1113 else if (code1
== PLUS
)
1115 rtx add_op0
= XEXP (op1
, 0);
1116 rtx add_op1
= XEXP (op1
, 1);
1118 if (GET_CODE (XEXP (op1
, 1)) == REG
&& GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
1120 add_op0
= XEXP (op1
, 1); /* reverse operands */
1121 add_op1
= XEXP (op1
, 0);
1124 operands
[2] = add_op0
;
1125 operands
[3] = add_op1
;
1126 ret
= "add%:\t%0,%2,%3";
1130 else if (code0
== MEM
)
1133 mips_count_memory_refs (op0
, 1);
1137 int regno1
= REGNO (op1
) + subreg_word1
;
1139 if (GP_REG_P (regno1
))
1144 case SFmode
: ret
= "sw\t%1,%0"; break;
1145 case SImode
: ret
= "sw\t%1,%0"; break;
1146 case HImode
: ret
= "sh\t%1,%0"; break;
1147 case QImode
: ret
= "sb\t%1,%0"; break;
1151 else if (FP_REG_P (regno1
) && (mode
== SImode
|| mode
== SFmode
))
1155 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1160 case SFmode
: ret
= "sw\t%z1,%0"; break;
1161 case SImode
: ret
= "sw\t%z1,%0"; break;
1162 case HImode
: ret
= "sh\t%z1,%0"; break;
1163 case QImode
: ret
= "sb\t%z1,%0"; break;
1167 else if (code1
== CONST_DOUBLE
&& op1
== CONST0_RTX (mode
))
1172 case SFmode
: ret
= "sw\t%.,%0"; break;
1173 case SImode
: ret
= "sw\t%.,%0"; break;
1174 case HImode
: ret
= "sh\t%.,%0"; break;
1175 case QImode
: ret
= "sb\t%.,%0"; break;
1179 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1181 int i
= strlen (ret
);
1182 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1185 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1186 ret
= volatile_buffer
;
1190 if (ret
== (char *)0)
1192 abort_with_insn (insn
, "Bad move");
1196 if (delay
!= DELAY_NONE
)
1197 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1203 /* Return the appropriate instructions to move 2 words */
1206 mips_move_2words (operands
, insn
)
1211 rtx op0
= operands
[0];
1212 rtx op1
= operands
[1];
1213 enum rtx_code code0
= GET_CODE (operands
[0]);
1214 enum rtx_code code1
= GET_CODE (operands
[1]);
1215 int subreg_word0
= 0;
1216 int subreg_word1
= 0;
1217 enum delay_type delay
= DELAY_NONE
;
1219 while (code0
== SUBREG
)
1221 subreg_word0
+= SUBREG_WORD (op0
);
1222 op0
= SUBREG_REG (op0
);
1223 code0
= GET_CODE (op0
);
1226 while (code1
== SUBREG
)
1228 subreg_word1
+= SUBREG_WORD (op1
);
1229 op1
= SUBREG_REG (op1
);
1230 code1
= GET_CODE (op1
);
1235 int regno0
= REGNO (op0
) + subreg_word0
;
1239 int regno1
= REGNO (op1
) + subreg_word1
;
1241 /* Just in case, don't do anything for assigning a register
1242 to itself, unless we are filling a delay slot. */
1243 if (regno0
== regno1
&& set_nomacro
== 0)
1246 else if (FP_REG_P (regno0
))
1248 if (FP_REG_P (regno1
))
1249 ret
= "mov.d\t%0,%1";
1257 abort_with_insn (insn
, "Bad move");
1258 #ifdef TARGET_FP_CALL_32
1259 if (FP_CALL_GP_REG_P (regno1
))
1260 ret
= "dsll\t%1,32\n\tor\t%1,%D1\n\tdmtc1\t%1,%0";
1263 ret
= "dmtc1\t%1,%0";
1266 ret
= "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";
1270 else if (FP_REG_P (regno1
))
1276 abort_with_insn (insn
, "Bad move");
1277 #ifdef TARGET_FP_CALL_32
1278 if (FP_CALL_GP_REG_P (regno0
))
1279 ret
= "dmfc1\t%0,%1\n\tmfc1\t%D0,%1\n\tdsrl\t%0,32";
1282 ret
= "dmfc1\t%0,%1";
1285 ret
= "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";
1288 else if (MD_REG_P (regno0
) && GP_REG_P (regno1
))
1294 ret
= "mthi\t%M1\n\tmtlo\t%L1";
1297 else if (GP_REG_P (regno0
) && MD_REG_P (regno1
))
1303 ret
= "mfhi\t%M0\n\tmflo\t%L0";
1306 else if (TARGET_64BIT
)
1307 ret
= "move\t%0,%1";
1309 else if (regno0
!= (regno1
+1))
1310 ret
= "move\t%0,%1\n\tmove\t%D0,%D1";
1313 ret
= "move\t%D0,%D1\n\tmove\t%0,%1";
1316 else if (code1
== CONST_DOUBLE
)
1318 /* Move zero from $0 unless !TARGET_64BIT and recipient
1319 is 64-bit fp reg, in which case generate a constant. */
1320 if (op1
!= CONST0_RTX (GET_MODE (op1
))
1321 || (TARGET_FLOAT64
&& !TARGET_64BIT
&& FP_REG_P (regno0
)))
1323 if (GET_MODE (op1
) == DFmode
)
1326 #ifdef TARGET_FP_CALL_32
1327 if (FP_CALL_GP_REG_P (regno0
))
1329 if (TARGET_FLOAT64
&& !TARGET_64BIT
)
1331 operands
[2] = GEN_INT (CONST_DOUBLE_LOW (op1
));
1332 operands
[3] = GEN_INT (CONST_DOUBLE_HIGH (op1
));
1333 ret
= "li\t%M0,%3\n\tli\t%L0,%2";
1336 ret
= "li.d\t%0,%1\n\tdsll\t%D0,%0,32\n\tdsrl\t%D0,32\n\tdsrl\t%0,32";
1340 ret
= "li.d\t%0,%1";
1343 else if (TARGET_FLOAT64
)
1348 operands
[2] = GEN_INT (CONST_DOUBLE_LOW (op1
));
1349 operands
[3] = GEN_INT (CONST_DOUBLE_HIGH (op1
));
1350 ret
= "li\t%M0,%3\n\tli\t%L0,%2";
1356 if (GP_REG_P (regno0
))
1358 #ifdef TARGET_FP_CALL_32
1359 && ! FP_CALL_GP_REG_P (regno0
)
1363 : "move\t%0,%.\n\tmove\t%D0,%.";
1365 else if (FP_REG_P (regno0
))
1368 ret
= (TARGET_64BIT
)
1370 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1375 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1377 if (GP_REG_P (regno0
))
1378 ret
= (TARGET_64BIT
)
1380 : "move\t%0,%.\n\tmove\t%D0,%.";
1382 else if (FP_REG_P (regno0
))
1385 ret
= (TARGET_64BIT
)
1389 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0");
1393 else if (code1
== CONST_INT
&& GET_MODE (op0
) == DImode
&& GP_REG_P (regno0
))
1399 operands
[2] = GEN_INT (INTVAL (operands
[1]) >= 0 ? 0 : -1);
1400 ret
= "li\t%M0,%2\n\tli\t%L0,%1";
1404 else if (code1
== MEM
)
1409 mips_count_memory_refs (op1
, 2);
1411 if (FP_REG_P (regno0
))
1414 else if (TARGET_64BIT
)
1416 #ifdef TARGET_FP_CALL_32
1417 if (FP_CALL_GP_REG_P (regno0
))
1419 if (offsettable_address_p (FALSE
, SImode
, op1
))
1420 ret
= "lwu\t%0,%1\n\tlwu\t%D0,4+%1";
1422 ret
= "ld\t%0,%1\n\tdsll\t%D0,%0,32\n\tdsrl\t%D0,32\n\tdsrl\t%0,32";
1429 else if (offsettable_address_p (1, DFmode
, XEXP (op1
, 0)))
1431 operands
[2] = adj_offsettable_operand (op1
, 4);
1432 if (reg_mentioned_p (op0
, op1
))
1433 ret
= "lw\t%D0,%2\n\tlw\t%0,%1";
1435 ret
= "lw\t%0,%1\n\tlw\t%D0,%2";
1438 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1440 int i
= strlen (ret
);
1441 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1444 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1445 ret
= volatile_buffer
;
1449 else if (code1
== LABEL_REF
1450 || code1
== SYMBOL_REF
1455 return mips_move_1word (operands
, insn
, 0);
1459 else if (code0
== MEM
)
1463 int regno1
= REGNO (op1
) + subreg_word1
;
1465 if (FP_REG_P (regno1
))
1468 else if (TARGET_64BIT
)
1470 #ifdef TARGET_FP_CALL_32
1471 if (FP_CALL_GP_REG_P (regno1
))
1472 ret
= "dsll\t%1,32\n\tor\t%1,%D1\n\tsd\t%1,%0";
1478 else if (offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1480 operands
[2] = adj_offsettable_operand (op0
, 4);
1481 ret
= "sw\t%1,%0\n\tsw\t%D1,%2";
1485 else if (((code1
== CONST_INT
&& INTVAL (op1
) == 0)
1486 || (code1
== CONST_DOUBLE
1487 && op1
== CONST0_RTX (GET_MODE (op1
))))
1489 || offsettable_address_p (1, DFmode
, XEXP (op0
, 0))))
1495 operands
[2] = adj_offsettable_operand (op0
, 4);
1496 ret
= "sw\t%.,%0\n\tsw\t%.,%2";
1501 mips_count_memory_refs (op0
, 2);
1503 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1505 int i
= strlen (ret
);
1506 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1509 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1510 ret
= volatile_buffer
;
1514 if (ret
== (char *)0)
1516 abort_with_insn (insn
, "Bad move");
1520 if (delay
!= DELAY_NONE
)
1521 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1527 /* Provide the costs of an addressing mode that contains ADDR.
1528 If ADDR is not a valid address, its cost is irrelevant. */
1531 mips_address_cost (addr
)
1534 switch (GET_CODE (addr
))
1548 rtx offset
= const0_rtx
;
1549 addr
= eliminate_constant_term (XEXP (addr
, 0), &offset
);
1550 if (GET_CODE (addr
) == LABEL_REF
)
1553 if (GET_CODE (addr
) != SYMBOL_REF
)
1556 if (! SMALL_INT (offset
))
1562 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
1566 register rtx plus0
= XEXP (addr
, 0);
1567 register rtx plus1
= XEXP (addr
, 1);
1569 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1571 plus0
= XEXP (addr
, 1);
1572 plus1
= XEXP (addr
, 0);
1575 if (GET_CODE (plus0
) != REG
)
1578 switch (GET_CODE (plus1
))
1584 return (SMALL_INT (plus1
) ? 1 : 2);
1591 return mips_address_cost (plus1
) + 1;
1599 /* Return true if X is an address which needs a temporary register when
1600 reloaded while generating PIC code. */
1603 pic_address_needs_scratch (x
)
1606 /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
1607 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
1608 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
1609 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
1610 && ! SMALL_INT (XEXP (XEXP (x
, 0), 1)))
1616 /* Make normal rtx_code into something we can index from an array */
1618 static enum internal_test
1619 map_test_to_internal_test (test_code
)
1620 enum rtx_code test_code
;
1622 enum internal_test test
= ITEST_MAX
;
1627 case EQ
: test
= ITEST_EQ
; break;
1628 case NE
: test
= ITEST_NE
; break;
1629 case GT
: test
= ITEST_GT
; break;
1630 case GE
: test
= ITEST_GE
; break;
1631 case LT
: test
= ITEST_LT
; break;
1632 case LE
: test
= ITEST_LE
; break;
1633 case GTU
: test
= ITEST_GTU
; break;
1634 case GEU
: test
= ITEST_GEU
; break;
1635 case LTU
: test
= ITEST_LTU
; break;
1636 case LEU
: test
= ITEST_LEU
; break;
1643 /* Generate the code to compare two integer values. The return value is:
1644 (reg:SI xx) The pseudo register the comparison is in
1645 (rtx)0 No register, generate a simple branch.
1647 ??? This is called with result nonzero by the Scond patterns in
1648 mips.md. These patterns are called with a target in the mode of
1649 the Scond instruction pattern. Since this must be a constant, we
1650 must use SImode. This means that if RESULT is non-zero, it will
1651 always be an SImode register, even if TARGET_64BIT is true. We
1652 cope with this by calling convert_move rather than emit_move_insn.
1653 This will sometimes lead to an unnecessary extension of the result;
1665 gen_int_relational (test_code
, result
, cmp0
, cmp1
, p_invert
)
1666 enum rtx_code test_code
; /* relational test (EQ, etc) */
1667 rtx result
; /* result to store comp. or 0 if branch */
1668 rtx cmp0
; /* first operand to compare */
1669 rtx cmp1
; /* second operand to compare */
1670 int *p_invert
; /* NULL or ptr to hold whether branch needs */
1671 /* to reverse its test */
1674 enum rtx_code test_code
; /* code to use in instruction (LT vs. LTU) */
1675 int const_low
; /* low bound of constant we can accept */
1676 int const_high
; /* high bound of constant we can accept */
1677 int const_add
; /* constant to add (convert LE -> LT) */
1678 int reverse_regs
; /* reverse registers in test */
1679 int invert_const
; /* != 0 if invert value if cmp1 is constant */
1680 int invert_reg
; /* != 0 if invert value if cmp1 is register */
1681 int unsignedp
; /* != 0 for unsigned comparisons. */
1684 static struct cmp_info info
[ (int)ITEST_MAX
] = {
1686 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1687 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1688 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1689 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1690 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1691 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1692 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1693 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1694 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1695 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1698 enum internal_test test
;
1699 enum machine_mode mode
;
1700 struct cmp_info
*p_info
;
1707 test
= map_test_to_internal_test (test_code
);
1708 if (test
== ITEST_MAX
)
1711 p_info
= &info
[ (int)test
];
1712 eqne_p
= (p_info
->test_code
== XOR
);
1714 mode
= GET_MODE (cmp0
);
1715 if (mode
== VOIDmode
)
1716 mode
= GET_MODE (cmp1
);
1718 /* Eliminate simple branches */
1719 branch_p
= (result
== (rtx
)0);
1722 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
1724 /* Comparisons against zero are simple branches */
1725 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1728 /* Test for beq/bne. */
1733 /* allocate a pseudo to calculate the value in. */
1734 result
= gen_reg_rtx (mode
);
1737 /* Make sure we can handle any constants given to us. */
1738 if (GET_CODE (cmp0
) == CONST_INT
)
1739 cmp0
= force_reg (mode
, cmp0
);
1741 if (GET_CODE (cmp1
) == CONST_INT
)
1743 HOST_WIDE_INT value
= INTVAL (cmp1
);
1744 if (value
< p_info
->const_low
1745 || value
> p_info
->const_high
1746 /* ??? Why? And why wasn't the similar code below modified too? */
1748 && HOST_BITS_PER_WIDE_INT
< 64
1749 && p_info
->const_add
!= 0
1750 && ((p_info
->unsignedp
1751 ? ((unsigned HOST_WIDE_INT
) (value
+ p_info
->const_add
)
1753 : (value
+ p_info
->const_add
) > INTVAL (cmp1
))
1754 != (p_info
->const_add
> 0))))
1755 cmp1
= force_reg (mode
, cmp1
);
1758 /* See if we need to invert the result. */
1759 invert
= (GET_CODE (cmp1
) == CONST_INT
)
1760 ? p_info
->invert_const
1761 : p_info
->invert_reg
;
1763 if (p_invert
!= (int *)0)
1769 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1770 Comparison between two registers, may involve switching operands. */
1771 if (GET_CODE (cmp1
) == CONST_INT
)
1773 if (p_info
->const_add
!= 0)
1775 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
1776 /* If modification of cmp1 caused overflow,
1777 we would get the wrong answer if we follow the usual path;
1778 thus, x > 0xffffffffu would turn into x > 0u. */
1779 if ((p_info
->unsignedp
1780 ? (unsigned HOST_WIDE_INT
) new > INTVAL (cmp1
)
1781 : new > INTVAL (cmp1
))
1782 != (p_info
->const_add
> 0))
1784 /* This test is always true, but if INVERT is true then
1785 the result of the test needs to be inverted so 0 should
1786 be returned instead. */
1787 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1791 cmp1
= GEN_INT (new);
1794 else if (p_info
->reverse_regs
)
1801 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1805 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (mode
) : result
;
1806 convert_move (reg
, gen_rtx (p_info
->test_code
, mode
, cmp0
, cmp1
), 0);
1809 if (test
== ITEST_NE
)
1811 convert_move (result
, gen_rtx (GTU
, mode
, reg
, const0_rtx
), 0);
1815 else if (test
== ITEST_EQ
)
1817 reg2
= (invert
) ? gen_reg_rtx (mode
) : result
;
1818 convert_move (reg2
, gen_rtx (LTU
, mode
, reg
, const1_rtx
), 0);
1823 convert_move (result
, gen_rtx (XOR
, mode
, reg
, const1_rtx
), 0);
1829 /* Emit the common code for doing conditional branches.
1830 operand[0] is the label to jump to.
1831 The comparison operands are saved away by cmp{si,di,sf,df}. */
1834 gen_conditional_branch (operands
, test_code
)
1836 enum rtx_code test_code
;
1838 static enum machine_mode mode_map
[(int)CMP_MAX
][(int)ITEST_MAX
] = {
1865 CC_REV_FPmode
, /* ne */
1877 CC_REV_FPmode
, /* ne */
1889 enum machine_mode mode
;
1890 enum cmp_type type
= branch_type
;
1891 rtx cmp0
= branch_cmp
[0];
1892 rtx cmp1
= branch_cmp
[1];
1893 rtx label1
= gen_rtx (LABEL_REF
, VOIDmode
, operands
[0]);
1894 rtx label2
= pc_rtx
;
1897 enum internal_test test
= map_test_to_internal_test (test_code
);
1899 if (test
== ITEST_MAX
)
1905 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
1906 mode
= mode_map
[(int)type
][(int)test
];
1907 if (mode
== VOIDmode
)
1917 reg
= gen_int_relational (test_code
, (rtx
)0, cmp0
, cmp1
, &invert
);
1925 /* Make sure not non-zero constant if ==/!= */
1926 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1927 cmp1
= force_reg (mode
, cmp1
);
1934 rtx reg
= gen_rtx (REG
, mode
, FPSW_REGNUM
);
1935 emit_insn (gen_rtx (SET
, VOIDmode
, reg
, gen_rtx (test_code
, mode
, cmp0
, cmp1
)));
1943 /* Generate the jump */
1950 emit_jump_insn (gen_rtx (SET
, VOIDmode
,
1952 gen_rtx (IF_THEN_ELSE
, VOIDmode
,
1953 gen_rtx (test_code
, mode
, cmp0
, cmp1
),
1960 abort_with_insn (gen_rtx (test_code
, mode
, cmp0
, cmp1
), "bad test");
1965 /* Internal code to generate the load and store of one word/short/byte.
1966 The load is emitted directly, and the store insn is returned. */
1968 #define UNITS_PER_MIPS_DWORD 8
1969 #define UNITS_PER_MIPS_WORD 4
1970 #define UNITS_PER_MIPS_HWORD 2
1973 block_move_load_store (dest_reg
, src_reg
, p_bytes
, p_offset
, align
, orig_src
)
1974 rtx src_reg
; /* register holding source memory address */
1975 rtx dest_reg
; /* register holding dest. memory address */
1976 int *p_bytes
; /* pointer to # bytes remaining */
1977 int *p_offset
; /* pointer to current offset */
1978 int align
; /* alignment */
1979 rtx orig_src
; /* original source for making a reg note */
1981 int bytes
; /* # bytes remaining */
1982 int offset
; /* offset to use */
1983 int size
; /* size in bytes of load/store */
1984 enum machine_mode mode
; /* mode to use for load/store */
1985 rtx reg
; /* temporary register */
1986 rtx src_addr
; /* source address */
1987 rtx dest_addr
; /* destination address */
1988 rtx insn
; /* insn of the load */
1989 rtx orig_src_addr
; /* original source address */
1990 rtx (*load_func
)(); /* function to generate load insn */
1991 rtx (*store_func
)(); /* function to generate destination insn */
1994 if (bytes
<= 0 || align
<= 0)
1997 if (bytes
>= UNITS_PER_MIPS_DWORD
&& align
>= UNIS_PER_MIPS_DWORD
)
2000 size
= UNITS_PER_MIPS_DWORD
;
2001 load_func
= gen_movdi
;
2002 store_func
= gen_movdi
;
2004 else if (bytes
>= UNITS_PER_MIPS_WORD
&& align
>= UNITS_PER_MIPS_WORD
)
2007 size
= UNITS_PER_MIPS_WORD
;
2008 load_func
= gen_movsi
;
2009 store_func
= gen_movsi
;
2013 /* Don't generate unaligned moves here, rather defer those to the
2014 general movestrsi_internal pattern.
2015 If this gets commented back in, then should add the dword equivalent. */
2016 else if (bytes
>= UNITS_PER_MIPS_WORD
)
2019 size
= UNITS_PER_MIPS_WORD
;
2020 load_func
= gen_movsi_ulw
;
2021 store_func
= gen_movsi_usw
;
2025 else if (bytes
>= UNITS_PER_MIPS_SHORT
&& align
>= UNITS_PER_MIPS_SHORT
)
2028 size
= UNITS_PER_MIPS_SHORT
;
2029 load_func
= gen_movhi
;
2030 store_func
= gen_movhi
;
2037 load_func
= gen_movqi
;
2038 store_func
= gen_movqi
;
2042 *p_offset
= offset
+ size
;
2043 *p_bytes
= bytes
- size
;
2048 dest_addr
= dest_reg
;
2052 src_addr
= gen_rtx (PLUS
, Pmode
, src_reg
, GEN_INT (offset
));
2053 dest_addr
= gen_rtx (PLUS
, Pmode
, dest_reg
, GEN_INT (offset
));
2056 reg
= gen_reg_rtx (mode
);
2057 insn
= emit_insn ((*load_func
) (reg
, gen_rtx (MEM
, mode
, src_addr
)));
2058 orig_src_addr
= XEXP (orig_src
, 0);
2059 if (CONSTANT_P (orig_src_addr
))
2060 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUIV
,
2061 plus_constant (orig_src_addr
, offset
),
2064 return (*store_func
) (gen_rtx (MEM
, mode
, dest_addr
), reg
);
2069 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows:
2081 This way, no NOP's are needed, except at the end, and only
2082 two temp registers are needed. Two delay slots are used
2083 in deference to the R4000. */
2087 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
)
2088 rtx dest_reg
; /* register holding destination address */
2089 rtx src_reg
; /* register holding source address */
2090 int bytes
; /* # bytes to move */
2091 int align
; /* max alignment to assume */
2092 rtx orig_src
; /* original source for making a reg note */
2095 rtx prev2_store
= (rtx
)0;
2096 rtx prev_store
= (rtx
)0;
2097 rtx cur_store
= (rtx
)0;
2101 /* Is there a store to do? */
2103 emit_insn (prev2_store
);
2105 prev2_store
= prev_store
;
2106 prev_store
= cur_store
;
2107 cur_store
= block_move_load_store (dest_reg
, src_reg
,
2112 /* Finish up last three stores. */
2114 emit_insn (prev2_store
);
2117 emit_insn (prev_store
);
2120 emit_insn (cur_store
);
2125 /* Write a loop to move a constant number of bytes. Generate load/stores as follows:
2131 temp<last> = src[MAX_MOVE_REGS-1];
2135 dest[MAX_MOVE_REGS-1] = temp<last>;
2136 src += MAX_MOVE_REGS;
2137 dest += MAX_MOVE_REGS;
2138 } while (src != final);
2140 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp
2141 registers are needed.
2143 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3
2144 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every
2145 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */
2147 #define MAX_MOVE_REGS 4
2148 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2150 /* ??? Should add code to use DWORD load/stores. */
2153 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
)
2154 rtx dest_reg
; /* register holding destination address */
2155 rtx src_reg
; /* register holding source address */
2156 int bytes
; /* # bytes to move */
2157 int align
; /* alignment */
2158 rtx orig_src
; /* original source for making a reg note */
2160 rtx dest_mem
= gen_rtx (MEM
, BLKmode
, dest_reg
);
2161 rtx src_mem
= gen_rtx (MEM
, BLKmode
, src_reg
);
2162 rtx align_rtx
= GEN_INT (align
);
2168 if (bytes
< 2*MAX_MOVE_BYTES
)
2171 leftover
= bytes
% MAX_MOVE_BYTES
;
2174 label
= gen_label_rtx ();
2175 final_src
= gen_reg_rtx (Pmode
);
2176 bytes_rtx
= GEN_INT (bytes
);
2182 emit_insn (gen_movdi (final_src
, bytes_rtx
));
2183 emit_insn (gen_adddi3 (final_src
, final_src
, src_reg
));
2187 emit_insn (gen_movsi (final_src
, bytes_rtx
));
2188 emit_insn (gen_addsi3 (final_src
, final_src
, src_reg
));
2194 emit_insn (gen_adddi3 (final_src
, src_reg
, bytes_rtx
));
2196 emit_insn (gen_addsi3 (final_src
, src_reg
, bytes_rtx
));
2201 bytes_rtx
= GEN_INT (MAX_MOVE_BYTES
);
2202 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
, bytes_rtx
, align_rtx
));
2205 emit_insn (gen_adddi3 (src_reg
, src_reg
, bytes_rtx
));
2206 emit_insn (gen_adddi3 (dest_reg
, dest_reg
, bytes_rtx
));
2207 emit_insn (gen_cmpdi (src_reg
, final_src
));
2211 emit_insn (gen_addsi3 (src_reg
, src_reg
, bytes_rtx
));
2212 emit_insn (gen_addsi3 (dest_reg
, dest_reg
, bytes_rtx
));
2213 emit_insn (gen_cmpsi (src_reg
, final_src
));
2215 emit_jump_insn (gen_bne (label
));
2218 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
,
2224 /* Use a library function to move some bytes. */
2227 block_move_call (dest_reg
, src_reg
, bytes_rtx
)
2232 /* We want to pass the size as Pmode, which will normally be SImode
2233 but will be DImode if we are using 64 bit longs and pointers. */
2234 if (GET_MODE (bytes_rtx
) != VOIDmode
2235 && GET_MODE (bytes_rtx
) != Pmode
)
2236 bytes_rtx
= convert_to_mode (Pmode
, bytes_rtx
, TRUE
);
2238 #ifdef TARGET_MEM_FUNCTIONS
2239 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "memcpy"), 0,
2245 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "bcopy"), 0,
2254 /* Expand string/block move operations.
2256 operands[0] is the pointer to the destination.
2257 operands[1] is the pointer to the source.
2258 operands[2] is the number of bytes to move.
2259 operands[3] is the alignment. */
2262 expand_block_move (operands
)
2265 rtx bytes_rtx
= operands
[2];
2266 rtx align_rtx
= operands
[3];
2267 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2268 int bytes
= (constp
? INTVAL (bytes_rtx
) : 0);
2269 int align
= INTVAL (align_rtx
);
2270 rtx orig_src
= operands
[1];
2274 if (constp
&& bytes
<= 0)
2277 if (align
> UNITS_PER_WORD
)
2278 align
= UNITS_PER_WORD
;
2280 /* Move the address into scratch registers. */
2281 dest_reg
= copy_addr_to_reg (XEXP (operands
[0], 0));
2282 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2285 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2288 else if (constp
&& bytes
<= 3*align
)
2289 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2292 else if (constp
&& bytes
<= 2*MAX_MOVE_BYTES
)
2293 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2294 gen_rtx (MEM
, BLKmode
, src_reg
),
2295 bytes_rtx
, align_rtx
));
2297 else if (constp
&& align
>= UNITS_PER_WORD
&& optimize
)
2298 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2300 else if (constp
&& optimize
)
2302 /* If the alignment is not word aligned, generate a test at
2303 runtime, to see whether things wound up aligned, and we
2304 can use the faster lw/sw instead ulw/usw. */
2306 rtx temp
= gen_reg_rtx (Pmode
);
2307 rtx aligned_label
= gen_label_rtx ();
2308 rtx join_label
= gen_label_rtx ();
2309 int leftover
= bytes
% MAX_MOVE_BYTES
;
2315 emit_insn (gen_iordi3 (temp
, src_reg
, dest_reg
));
2316 emit_insn (gen_anddi3 (temp
, temp
, GEN_INT (UNITS_PER_WORD
-1)));
2317 emit_insn (gen_cmpdi (temp
, const0_rtx
));
2321 emit_insn (gen_iorsi3 (temp
, src_reg
, dest_reg
));
2322 emit_insn (gen_andsi3 (temp
, temp
, GEN_INT (UNITS_PER_WORD
-1)));
2323 emit_insn (gen_cmpsi (temp
, const0_rtx
));
2325 emit_jump_insn (gen_beq (aligned_label
));
2327 /* Unaligned loop. */
2328 block_move_loop (dest_reg
, src_reg
, bytes
, 1, orig_src
);
2329 emit_jump_insn (gen_jump (join_label
));
2333 emit_label (aligned_label
);
2334 block_move_loop (dest_reg
, src_reg
, bytes
, UNITS_PER_WORD
, orig_src
);
2335 emit_label (join_label
);
2337 /* Bytes at the end of the loop. */
2341 if (leftover
<= 3*align
)
2342 block_move_sequence (dest_reg
, src_reg
, leftover
, align
, orig_src
);
2346 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2347 gen_rtx (MEM
, BLKmode
, src_reg
),
2354 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2358 /* Emit load/stores for a small constant block_move.
2360 operands[0] is the memory address of the destination.
2361 operands[1] is the memory address of the source.
2362 operands[2] is the number of bytes to move.
2363 operands[3] is the alignment.
2364 operands[4] is a temp register.
2365 operands[5] is a temp register.
2367 operands[3+num_regs] is the last temp register.
2369 The block move type can be one of the following:
2370 BLOCK_MOVE_NORMAL Do all of the block move.
2371 BLOCK_MOVE_NOT_LAST Do all but the last store.
2372 BLOCK_MOVE_LAST Do just the last store. */
2375 output_block_move (insn
, operands
, num_regs
, move_type
)
2379 enum block_move_type move_type
;
2381 rtx dest_reg
= XEXP (operands
[0], 0);
2382 rtx src_reg
= XEXP (operands
[1], 0);
2383 int bytes
= INTVAL (operands
[2]);
2384 int align
= INTVAL (operands
[3]);
2387 int use_lwl_lwr
= FALSE
;
2388 int last_operand
= num_regs
+4;
2394 char *load
; /* load insn without nop */
2395 char *load_nop
; /* load insn with trailing nop */
2396 char *store
; /* store insn */
2397 char *final
; /* if last_store used: NULL or swr */
2398 char *last_store
; /* last store instruction */
2399 int offset
; /* current offset */
2400 enum machine_mode mode
; /* mode to use on (MEM) */
2403 /* Detect a bug in GCC, where it can give us a register
2404 the same as one of the addressing registers and reduce
2405 the number of registers available. */
2407 i
< last_operand
&& safe_regs
< (sizeof(xoperands
) / sizeof(xoperands
[0]));
2410 if (!reg_mentioned_p (operands
[i
], operands
[0])
2411 && !reg_mentioned_p (operands
[i
], operands
[1]))
2413 xoperands
[safe_regs
++] = operands
[i
];
2416 if (safe_regs
< last_operand
)
2418 xoperands
[0] = operands
[0];
2419 xoperands
[1] = operands
[1];
2420 xoperands
[2] = operands
[2];
2421 xoperands
[3] = operands
[3];
2422 return output_block_move (insn
, xoperands
, safe_regs
-4, move_type
);
2425 /* If we are given global or static addresses, and we would be
2426 emitting a few instructions, try to save time by using a
2427 temporary register for the pointer. */
2428 if (num_regs
> 2 && (bytes
> 2*align
|| move_type
!= BLOCK_MOVE_NORMAL
))
2430 if (CONSTANT_P (src_reg
))
2433 mips_count_memory_refs (operands
[1], 1);
2435 src_reg
= operands
[ 3 + num_regs
-- ];
2436 if (move_type
!= BLOCK_MOVE_LAST
)
2438 xoperands
[1] = operands
[1];
2439 xoperands
[0] = src_reg
;
2440 output_asm_insn ("la\t%0,%1", xoperands
);
2444 if (CONSTANT_P (dest_reg
))
2447 mips_count_memory_refs (operands
[0], 1);
2449 dest_reg
= operands
[ 3 + num_regs
-- ];
2450 if (move_type
!= BLOCK_MOVE_LAST
)
2452 xoperands
[1] = operands
[0];
2453 xoperands
[0] = dest_reg
;
2454 output_asm_insn ("la\t%0,%1", xoperands
);
2459 if (num_regs
> (sizeof (load_store
) / sizeof (load_store
[0])))
2460 num_regs
= (sizeof (load_store
) / sizeof (load_store
[0]));
2462 else if (num_regs
< 1)
2463 abort_with_insn (insn
, "Cannot do block move, not enough scratch registers");
2467 load_store
[num
].offset
= offset
;
2469 if (TARGET_64BIT
&& bytes
>= 8 && align
>= 8)
2471 load_store
[num
].load
= "ld\t%0,%1";
2472 load_store
[num
].load_nop
= "ld\t%0,%1%#";
2473 load_store
[num
].store
= "sd\t%0,%1";
2474 load_store
[num
].last_store
= "sd\t%0,%1";
2475 load_store
[num
].final
= (char *)0;
2476 load_store
[num
].mode
= DImode
;
2481 /* ??? Fails because of a MIPS assembler bug? */
2482 else if (TARGET_64BIT
&& bytes
>= 8)
2484 #if BYTES_BIG_ENDIAN
2485 load_store
[num
].load
= "ldl\t%0,%1\n\tldr\t%0,%2";
2486 load_store
[num
].load_nop
= "ldl\t%0,%1\n\tldr\t%0,%2%#";
2487 load_store
[num
].store
= "sdl\t%0,%1\n\tsdr\t%0,%2";
2488 load_store
[num
].last_store
= "sdr\t%0,%2";
2489 load_store
[num
].final
= "sdl\t%0,%1";
2491 load_store
[num
].load
= "ldl\t%0,%2\n\tldr\t%0,%1";
2492 load_store
[num
].load_nop
= "ldl\t%0,%2\n\tldr\t%0,%1%#";
2493 load_store
[num
].store
= "sdl\t%0,%2\n\tsdr\t%0,%1";
2494 load_store
[num
].last_store
= "sdr\t%0,%1";
2495 load_store
[num
].final
= "sdl\t%0,%2";
2497 load_store
[num
].mode
= DImode
;
2503 else if (bytes
>= 4 && align
>= 4)
2505 load_store
[num
].load
= "lw\t%0,%1";
2506 load_store
[num
].load_nop
= "lw\t%0,%1%#";
2507 load_store
[num
].store
= "sw\t%0,%1";
2508 load_store
[num
].last_store
= "sw\t%0,%1";
2509 load_store
[num
].final
= (char *)0;
2510 load_store
[num
].mode
= SImode
;
2515 else if (bytes
>= 4)
2517 #if BYTES_BIG_ENDIAN
2518 load_store
[num
].load
= "lwl\t%0,%1\n\tlwr\t%0,%2";
2519 load_store
[num
].load_nop
= "lwl\t%0,%1\n\tlwr\t%0,%2%#";
2520 load_store
[num
].store
= "swl\t%0,%1\n\tswr\t%0,%2";
2521 load_store
[num
].last_store
= "swr\t%0,%2";
2522 load_store
[num
].final
= "swl\t%0,%1";
2524 load_store
[num
].load
= "lwl\t%0,%2\n\tlwr\t%0,%1";
2525 load_store
[num
].load_nop
= "lwl\t%0,%2\n\tlwr\t%0,%1%#";
2526 load_store
[num
].store
= "swl\t%0,%2\n\tswr\t%0,%1";
2527 load_store
[num
].last_store
= "swr\t%0,%1";
2528 load_store
[num
].final
= "swl\t%0,%2";
2530 load_store
[num
].mode
= SImode
;
2536 else if (bytes
>= 2 && align
>= 2)
2538 load_store
[num
].load
= "lh\t%0,%1";
2539 load_store
[num
].load_nop
= "lh\t%0,%1%#";
2540 load_store
[num
].store
= "sh\t%0,%1";
2541 load_store
[num
].last_store
= "sh\t%0,%1";
2542 load_store
[num
].final
= (char *)0;
2543 load_store
[num
].mode
= HImode
;
2550 load_store
[num
].load
= "lb\t%0,%1";
2551 load_store
[num
].load_nop
= "lb\t%0,%1%#";
2552 load_store
[num
].store
= "sb\t%0,%1";
2553 load_store
[num
].last_store
= "sb\t%0,%1";
2554 load_store
[num
].final
= (char *)0;
2555 load_store
[num
].mode
= QImode
;
2560 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2562 dslots_load_total
++;
2563 dslots_load_filled
++;
2565 if (CONSTANT_P (src_reg
))
2566 mips_count_memory_refs (src_reg
, 1);
2568 if (CONSTANT_P (dest_reg
))
2569 mips_count_memory_refs (dest_reg
, 1);
2572 /* Emit load/stores now if we have run out of registers or are
2573 at the end of the move. */
2575 if (++num
== num_regs
|| bytes
== 0)
2577 /* If only load/store, we need a NOP after the load. */
2580 load_store
[0].load
= load_store
[0].load_nop
;
2581 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2582 dslots_load_filled
--;
2585 if (move_type
!= BLOCK_MOVE_LAST
)
2587 for (i
= 0; i
< num
; i
++)
2594 if (GET_MODE (operands
[i
+4]) != load_store
[i
].mode
)
2595 operands
[i
+4] = gen_rtx (REG
, load_store
[i
].mode
, REGNO (operands
[i
+4]));
2597 offset
= load_store
[i
].offset
;
2598 xoperands
[0] = operands
[i
+4];
2599 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2600 plus_constant (src_reg
, offset
));
2605 extra_offset
= GET_MODE_SIZE (load_store
[i
].mode
) - 1;
2606 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2607 plus_constant (src_reg
,
2612 output_asm_insn (load_store
[i
].load
, xoperands
);
2616 for (i
= 0; i
< num
; i
++)
2618 int last_p
= (i
== num
-1 && bytes
== 0);
2619 int offset
= load_store
[i
].offset
;
2621 xoperands
[0] = operands
[i
+4];
2622 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2623 plus_constant (dest_reg
, offset
));
2629 extra_offset
= GET_MODE_SIZE (load_store
[i
].mode
) - 1;
2630 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2631 plus_constant (dest_reg
,
2636 if (move_type
== BLOCK_MOVE_NORMAL
)
2637 output_asm_insn (load_store
[i
].store
, xoperands
);
2639 else if (move_type
== BLOCK_MOVE_NOT_LAST
)
2642 output_asm_insn (load_store
[i
].store
, xoperands
);
2644 else if (load_store
[i
].final
!= (char *)0)
2645 output_asm_insn (load_store
[i
].final
, xoperands
);
2649 output_asm_insn (load_store
[i
].last_store
, xoperands
);
2652 num
= 0; /* reset load_store */
2653 use_lwl_lwr
= FALSE
;
2661 /* Argument support functions. */
2663 /* Initialize CUMULATIVE_ARGS for a function. */
2666 init_cumulative_args (cum
, fntype
, libname
)
2667 CUMULATIVE_ARGS
*cum
; /* argument info to initialize */
2668 tree fntype
; /* tree ptr for function decl */
2669 rtx libname
; /* SYMBOL_REF of library name or 0 */
2671 static CUMULATIVE_ARGS zero_cum
;
2672 tree param
, next_param
;
2674 if (TARGET_DEBUG_E_MODE
)
2676 fprintf (stderr
, "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype
);
2678 fputc ('\n', stderr
);
2682 tree ret_type
= TREE_TYPE (fntype
);
2683 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
2684 tree_code_name
[ (int)TREE_CODE (fntype
) ],
2685 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
2691 /* Determine if this function has variable arguments. This is
2692 indicated by the last argument being 'void_type_mode' if there
2693 are no variable arguments. The standard MIPS calling sequence
2694 passes all arguments in the general purpose registers in this
2697 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
2701 next_param
= TREE_CHAIN (param
);
2702 if (next_param
== (tree
)0 && TREE_VALUE (param
) != void_type_node
)
2703 cum
->gp_reg_found
= 1;
2707 /* Advance the argument to the next argument position. */
2710 function_arg_advance (cum
, mode
, type
, named
)
2711 CUMULATIVE_ARGS
*cum
; /* current arg information */
2712 enum machine_mode mode
; /* current arg mode */
2713 tree type
; /* type of the argument or 0 if lib support */
2714 int named
; /* whether or not the argument was named */
2716 if (TARGET_DEBUG_E_MODE
)
2718 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n\n",
2719 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2729 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
2730 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
2732 cum
->gp_reg_found
= 1;
2733 cum
->arg_words
+= ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
2738 cum
->gp_reg_found
= 1;
2739 cum
->arg_words
+= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
2748 cum
->arg_words
+= (TARGET_64BIT
? 1 : 2);
2752 cum
->gp_reg_found
= 1;
2753 cum
->arg_words
+= (TARGET_64BIT
? 1 : 2);
2759 cum
->gp_reg_found
= 1;
2765 /* Return an RTL expression containing the register for the given mode,
2766 or 0 if the argument is to be passed on the stack. */
2769 function_arg (cum
, mode
, type
, named
)
2770 CUMULATIVE_ARGS
*cum
; /* current arg information */
2771 enum machine_mode mode
; /* current arg mode */
2772 tree type
; /* type of the argument or 0 if lib support */
2773 int named
; /* != 0 for normal args, == 0 for ... args */
2778 int struct_p
= ((type
!= (tree
)0)
2779 && (TREE_CODE (type
) == RECORD_TYPE
2780 || TREE_CODE (type
) == UNION_TYPE
));
2782 if (TARGET_DEBUG_E_MODE
)
2784 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ",
2785 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2791 if (cum
->gp_reg_found
|| cum
->arg_number
>= 2 || TARGET_SOFT_FLOAT
)
2792 regbase
= GP_ARG_FIRST
;
2795 regbase
= FP_ARG_FIRST
;
2796 /* If the first arg was a float in a floating point register,
2797 then set bias to align this float arg properly. */
2798 if (cum
->arg_words
== 1)
2806 cum
->arg_words
+= (cum
->arg_words
& 1);
2807 regbase
= (cum
->gp_reg_found
|| TARGET_SOFT_FLOAT
|| cum
->arg_number
>= 2
2813 if (GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
2814 && GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
2817 /* Drops through. */
2819 if (type
!= (tree
)0 && TYPE_ALIGN (type
) > BITS_PER_WORD
2821 cum
->arg_words
+= (cum
->arg_words
& 1);
2823 regbase
= GP_ARG_FIRST
;
2830 regbase
= GP_ARG_FIRST
;
2835 cum
->arg_words
+= (cum
->arg_words
& 1);
2836 regbase
= GP_ARG_FIRST
;
2839 if (cum
->arg_words
>= MAX_ARGS_IN_REGISTERS
)
2841 if (TARGET_DEBUG_E_MODE
)
2842 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
2851 ret
= gen_rtx (REG
, mode
, regbase
+ cum
->arg_words
+ bias
);
2853 if (TARGET_DEBUG_E_MODE
)
2854 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ cum
->arg_words
+ bias
],
2855 struct_p
? ", [struct]" : "");
2857 /* The following is a hack in order to pass 1 byte structures
2858 the same way that the MIPS compiler does (namely by passing
2859 the structure in the high byte or half word of the register).
2860 This also makes varargs work. If we have such a structure,
2861 we save the adjustment RTL, and the call define expands will
2862 emit them. For the VOIDmode argument (argument after the
2863 last real argument), pass back a parallel vector holding each
2864 of the adjustments. */
2866 /* ??? function_arg can be called more than once for each argument.
2867 As a result, we compute more adjustments than we need here.
2868 See the CUMULATIVE_ARGS definition in mips.h. */
2870 /* ??? This scheme requires everything smaller than the word size to
2871 shifted to the left, but when TARGET_64BIT and ! TARGET_INT64,
2872 that would mean every int needs to be shifted left, which is very
2873 inefficient. Let's not carry this compatibility to the 64 bit
2874 calling convention for now. */
2876 if (struct_p
&& int_size_in_bytes (type
) < UNITS_PER_WORD
2879 rtx amount
= GEN_INT (BITS_PER_WORD
2880 - int_size_in_bytes (type
) * BITS_PER_UNIT
);
2881 rtx reg
= gen_rtx (REG
, word_mode
, regbase
+ cum
->arg_words
+ bias
);
2883 cum
->adjust
[ cum
->num_adjusts
++ ] = gen_ashldi3 (reg
, reg
, amount
);
2885 cum
->adjust
[ cum
->num_adjusts
++ ] = gen_ashlsi3 (reg
, reg
, amount
);
2889 if (mode
== VOIDmode
&& cum
->num_adjusts
> 0)
2890 ret
= gen_rtx (PARALLEL
, VOIDmode
, gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
2897 function_arg_partial_nregs (cum
, mode
, type
, named
)
2898 CUMULATIVE_ARGS
*cum
; /* current arg information */
2899 enum machine_mode mode
; /* current arg mode */
2900 tree type
; /* type of the argument or 0 if lib support */
2901 int named
; /* != 0 for normal args, == 0 for ... args */
2903 if ((mode
== BLKmode
2904 || GET_MODE_CLASS (mode
) != MODE_COMPLEX_INT
2905 || GET_MODE_CLASS (mode
) != MODE_COMPLEX_FLOAT
)
2906 && cum
->arg_words
< MAX_ARGS_IN_REGISTERS
)
2909 if (mode
== BLKmode
)
2910 words
= ((int_size_in_bytes (type
) + UNITS_PER_WORD
- 1)
2913 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2915 if (words
+ cum
->arg_words
<= MAX_ARGS_IN_REGISTERS
)
2916 return 0; /* structure fits in registers */
2918 if (TARGET_DEBUG_E_MODE
)
2919 fprintf (stderr
, "function_arg_partial_nregs = %d\n",
2920 MAX_ARGS_IN_REGISTERS
- cum
->arg_words
);
2922 return MAX_ARGS_IN_REGISTERS
- cum
->arg_words
;
2925 else if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
-1
2928 if (TARGET_DEBUG_E_MODE
)
2929 fprintf (stderr
, "function_arg_partial_nregs = 1\n");
2938 /* Print the options used in the assembly file. */
2940 static struct {char *name
; int value
;} target_switches
[]
2951 int mask
= TARGET_DEFAULT
;
2953 /* Allow assembly language comparisons with -mdebug eliminating the
2954 compiler version number and switch lists. */
2956 if (TARGET_DEBUG_MODE
)
2959 fprintf (out
, "\n # %s %s", language_string
, version_string
);
2960 #ifdef TARGET_VERSION_INTERNAL
2961 TARGET_VERSION_INTERNAL (out
);
2964 fprintf (out
, " compiled by GNU C\n\n");
2966 fprintf (out
, " compiled by CC\n\n");
2969 fprintf (out
, " # Cc1 defaults:");
2971 for (j
= 0; j
< sizeof target_switches
/ sizeof target_switches
[0]; j
++)
2973 if (target_switches
[j
].name
[0] != '\0'
2974 && target_switches
[j
].value
> 0
2975 && (target_switches
[j
].value
& mask
) == target_switches
[j
].value
)
2977 mask
&= ~ target_switches
[j
].value
;
2978 len
= strlen (target_switches
[j
].name
) + 1;
2979 if (len
+ line_len
> 79)
2982 fputs ("\n #", out
);
2984 fprintf (out
, " -m%s", target_switches
[j
].name
);
2989 fprintf (out
, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):",
2990 mips_section_threshold
, mips_cpu_string
, mips_isa
);
2993 for (p
= &save_argv
[1]; *p
!= (char *)0; p
++)
2998 len
= strlen (arg
) + 1;
2999 if (len
+ line_len
> 79)
3002 fputs ("\n #", out
);
3004 fprintf (out
, " %s", *p
);
3009 fputs ("\n\n", out
);
3013 /* Abort after printing out a specific insn. */
3016 abort_with_insn (insn
, reason
)
3025 /* Write a message to stderr (for use in macros expanded in files that do not
3026 include stdio.h). */
3032 fprintf (stderr
, s
, s1
, s2
);
3042 fprintf (stderr
, "compiling '%s' in '%s'\n",
3043 (current_function_name
!= (char *)0) ? current_function_name
: "<toplevel>",
3044 (current_function_file
!= (char *)0) ? current_function_file
: "<no file>");
3047 #endif /* SIGINFO */
3050 /* Set up the threshold for data to go into the small data area, instead
3051 of the normal data area, and detect any conflicts in the switches. */
3056 register int i
, start
;
3058 register enum machine_mode mode
;
3060 mips_section_threshold
= (g_switch_set
) ? g_switch_value
: MIPS_DEFAULT_GVALUE
;
3062 if (mips_section_threshold
<= 0)
3063 target_flags
&= ~MASK_GPOPT
;
3065 target_flags
|= MASK_GPOPT
;
3067 /* Get the architectural level. */
3068 if (mips_isa_string
== (char *)0)
3070 #ifdef MIPS_ISA_DEFAULT
3071 mips_isa
= MIPS_ISA_DEFAULT
;
3077 else if (isdigit (*mips_isa_string
))
3079 mips_isa
= atoi (mips_isa_string
);
3080 if (mips_isa
< 1 || mips_isa
> 3)
3082 error ("-mips%d not supported", mips_isa
);
3089 error ("bad value (%s) for -mips switch", mips_isa_string
);
3093 /* Identify the processor type */
3094 if (mips_cpu_string
== (char *)0
3095 || !strcmp (mips_cpu_string
, "default")
3096 || !strcmp (mips_cpu_string
, "DEFAULT"))
3101 mips_cpu_string
= "3000";
3102 mips_cpu
= PROCESSOR_R3000
;
3105 mips_cpu_string
= "6000";
3106 mips_cpu
= PROCESSOR_R6000
;
3109 mips_cpu_string
= "4000";
3110 mips_cpu
= PROCESSOR_R4000
;
3114 #ifdef MIPS_CPU_DEFAULT
3115 if (mips_isa_string
== (char *)0)
3117 mips_cpu_string
= MIPS_CPU_STRING_DEFAULT
;
3118 mips_cpu
= MIPS_CPU_DEFAULT
;
3125 char *p
= mips_cpu_string
;
3127 if (*p
== 'r' || *p
== 'R')
3130 /* Since there is no difference between a R2000 and R3000 in
3131 terms of the scheduler, we collapse them into just an R3000. */
3133 mips_cpu
= PROCESSOR_DEFAULT
;
3137 if (!strcmp (p
, "2000") || !strcmp (p
, "2k") || !strcmp (p
, "2K"))
3138 mips_cpu
= PROCESSOR_R3000
;
3142 if (!strcmp (p
, "3000") || !strcmp (p
, "3k") || !strcmp (p
, "3K"))
3143 mips_cpu
= PROCESSOR_R3000
;
3147 if (!strcmp (p
, "4000") || !strcmp (p
, "4k") || !strcmp (p
, "4K"))
3148 mips_cpu
= PROCESSOR_R4000
;
3149 /* The r4400 is exactly the same as the r4000 from the compiler's
3151 else if (!strcmp (p
, "4400"))
3152 mips_cpu
= PROCESSOR_R4000
;
3153 else if (!strcmp (p
, "4600"))
3154 mips_cpu
= PROCESSOR_R4600
;
3158 if (!strcmp (p
, "6000") || !strcmp (p
, "6k") || !strcmp (p
, "6K"))
3159 mips_cpu
= PROCESSOR_R6000
;
3163 if (!strcmp (p
, "orion"))
3164 mips_cpu
= PROCESSOR_R4600
;
3168 if (mips_cpu
== PROCESSOR_DEFAULT
)
3170 error ("bad value (%s) for -mcpu= switch", mips_cpu_string
);
3171 mips_cpu_string
= "default";
3175 if ((mips_cpu
== PROCESSOR_R3000
&& mips_isa
> 1)
3176 || (mips_cpu
== PROCESSOR_R6000
&& mips_isa
> 2))
3177 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
3179 /* make sure sizes of ints/longs/etc. are ok */
3183 fatal ("Only MIPS-III CPUs can support 64 bit ints");
3185 else if (TARGET_LONG64
)
3186 fatal ("Only MIPS-III CPUs can support 64 bit longs");
3188 else if (TARGET_FLOAT64
)
3189 fatal ("Only MIPS-III CPUs can support 64 bit fp registers");
3191 else if (TARGET_64BIT
)
3192 fatal ("Only MIPS-III CPUs can support 64 bit gp registers");
3195 /* Tell halfpic.c that we have half-pic code if we do. */
3196 if (TARGET_HALF_PIC
)
3199 /* -fpic (-KPIC) is the default when TARGET_ABICALLS is defined. We need
3200 to set flag_pic so that the LEGITIMATE_PIC_OPERAND_P macro will work. */
3201 /* ??? -non_shared turns off pic code generation, but this is not
3203 if (TARGET_ABICALLS
)
3205 mips_abicalls
= MIPS_ABICALLS_YES
;
3207 if (mips_section_threshold
> 0)
3208 warning ("-G is incompatible with PIC code which is the default");
3211 mips_abicalls
= MIPS_ABICALLS_NO
;
3213 /* -membedded-pic is a form of PIC code suitable for embedded
3214 systems. All calls are made using PC relative addressing, and
3215 all data is addressed using the $gp register. This requires gas,
3216 which does most of the work, and GNU ld, which automatically
3217 expands PC relative calls which are out of range into a longer
3218 instruction sequence. All gcc really does differently is
3219 generate a different sequence for a switch. */
3220 if (TARGET_EMBEDDED_PIC
)
3223 if (TARGET_ABICALLS
)
3224 warning ("-membedded-pic and -mabicalls are incompatible");
3226 warning ("-G and -membedded-pic are incompatible");
3227 /* Setting mips_section_threshold is not required, because gas
3228 will force everything to be GP addressable anyhow, but
3229 setting it will cause gcc to make better estimates of the
3230 number of instructions required to access a particular data
3232 mips_section_threshold
= 0x7fffffff;
3235 /* -mrnames says to use the MIPS software convention for register
3236 names instead of the hardware names (ie, $a0 instead of $4).
3237 We do this by switching the names in mips_reg_names, which the
3238 reg_names points into via the REGISTER_NAMES macro. */
3240 if (TARGET_NAME_REGS
)
3241 bcopy ((char *) mips_sw_reg_names
, (char *) mips_reg_names
, sizeof (mips_reg_names
));
3243 /* If this is OSF/1, set up a SIGINFO handler so we can see what function
3244 is currently being compiled. */
3246 if (getenv ("GCC_SIGINFO") != (char *)0)
3248 struct sigaction action
;
3249 action
.sa_handler
= siginfo
;
3251 action
.sa_flags
= SA_RESTART
;
3252 sigaction (SIGINFO
, &action
, (struct sigaction
*)0);
3257 #if defined(ultrix) || defined(__ultrix) || defined(__OSF1__) || defined(__osf__) || defined(osf)
3258 /* If -mstats and -quiet, make stderr line buffered. */
3259 if (quiet_flag
&& TARGET_STATS
)
3260 setvbuf (stderr
, (char *)0, _IOLBF
, BUFSIZ
);
3264 /* Initialize the high and low values for legitimate floating point
3265 constants. Rather than trying to get the accuracy down to the
3266 last bit, just use approximate ranges. */
3267 dfhigh
= REAL_VALUE_ATOF ("1.0e300", DFmode
);
3268 dflow
= REAL_VALUE_ATOF ("1.0e-300", DFmode
);
3269 sfhigh
= REAL_VALUE_ATOF ("1.0e38", SFmode
);
3270 sflow
= REAL_VALUE_ATOF ("1.0e-38", SFmode
);
3272 mips_print_operand_punct
['?'] = TRUE
;
3273 mips_print_operand_punct
['#'] = TRUE
;
3274 mips_print_operand_punct
['&'] = TRUE
;
3275 mips_print_operand_punct
['!'] = TRUE
;
3276 mips_print_operand_punct
['*'] = TRUE
;
3277 mips_print_operand_punct
['@'] = TRUE
;
3278 mips_print_operand_punct
['.'] = TRUE
;
3279 mips_print_operand_punct
['('] = TRUE
;
3280 mips_print_operand_punct
[')'] = TRUE
;
3281 mips_print_operand_punct
['['] = TRUE
;
3282 mips_print_operand_punct
[']'] = TRUE
;
3283 mips_print_operand_punct
['<'] = TRUE
;
3284 mips_print_operand_punct
['>'] = TRUE
;
3285 mips_print_operand_punct
['{'] = TRUE
;
3286 mips_print_operand_punct
['}'] = TRUE
;
3287 mips_print_operand_punct
['^'] = TRUE
;
3289 mips_char_to_class
['d'] = GR_REGS
;
3290 mips_char_to_class
['f'] = ((TARGET_HARD_FLOAT
) ? FP_REGS
: NO_REGS
);
3291 mips_char_to_class
['h'] = HI_REG
;
3292 mips_char_to_class
['l'] = LO_REG
;
3293 mips_char_to_class
['x'] = MD_REGS
;
3294 mips_char_to_class
['y'] = GR_REGS
;
3295 mips_char_to_class
['z'] = ST_REGS
;
3297 /* Set up array to map GCC register number to debug register number.
3298 Ignore the special purpose register numbers. */
3300 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3301 mips_dbx_regno
[i
] = -1;
3303 start
= GP_DBX_FIRST
- GP_REG_FIRST
;
3304 for (i
= GP_REG_FIRST
; i
<= GP_REG_LAST
; i
++)
3305 mips_dbx_regno
[i
] = i
+ start
;
3307 start
= FP_DBX_FIRST
- FP_REG_FIRST
;
3308 for (i
= FP_REG_FIRST
; i
<= FP_REG_LAST
; i
++)
3309 mips_dbx_regno
[i
] = i
+ start
;
3311 /* Set up array giving whether a given register can hold a given mode.
3312 At present, restrict ints from being in FP registers, because reload
3313 is a little enthusiastic about storing extra values in FP registers,
3314 and this is not good for things like OS kernels. Also, due to the
3315 mandatory delay, it is as fast to load from cached memory as to move
3316 from the FP register. */
3318 for (mode
= VOIDmode
;
3319 mode
!= MAX_MACHINE_MODE
;
3320 mode
= (enum machine_mode
)((int)mode
+ 1))
3322 register int size
= GET_MODE_SIZE (mode
);
3323 register enum mode_class
class = GET_MODE_CLASS (mode
);
3325 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
3329 if (mode
== CC_FPmode
|| mode
== CC_REV_FPmode
)
3330 temp
= (regno
== FPSW_REGNUM
);
3332 else if (GP_REG_P (regno
))
3333 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
3335 else if (FP_REG_P (regno
))
3336 temp
= ((TARGET_FLOAT64
|| ((regno
& 1) == 0))
3337 && (class == MODE_FLOAT
3338 || class == MODE_COMPLEX_FLOAT
3339 || (TARGET_DEBUG_H_MODE
&& class == MODE_INT
)));
3341 else if (MD_REG_P (regno
))
3344 temp
= (mode
== DImode
3345 || (regno
== MD_REG_FIRST
&& mode
== TImode
));
3347 temp
= (mode
== SImode
3348 || (regno
== MD_REG_FIRST
&& mode
== DImode
));
3354 mips_hard_regno_mode_ok
[(int)mode
][regno
] = temp
;
3361 * The MIPS debug format wants all automatic variables and arguments
3362 * to be in terms of the virtual frame pointer (stack pointer before
3363 * any adjustment in the function), while the MIPS 3.0 linker wants
3364 * the frame pointer to be the stack pointer after the initial
3365 * adjustment. So, we do the adjustment here. The arg pointer (which
3366 * is eliminated) points to the virtual frame pointer, while the frame
3367 * pointer (which may be eliminated) points to the stack pointer after
3368 * the initial adjustments.
3372 mips_debugger_offset (addr
, offset
)
3376 rtx offset2
= const0_rtx
;
3377 rtx reg
= eliminate_constant_term (addr
, &offset2
);
3380 offset
= INTVAL (offset2
);
3382 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
)
3384 int frame_size
= (!current_frame_info
.initialized
)
3385 ? compute_frame_size (get_frame_size ())
3386 : current_frame_info
.total_size
;
3388 offset
= offset
- frame_size
;
3390 /* sdbout_parms does not want this to crash for unrecognized cases. */
3392 else if (reg
!= arg_pointer_rtx
)
3393 abort_with_insn (addr
, "mips_debugger_offset called with non stack/frame/arg pointer.");
3400 /* A C compound statement to output to stdio stream STREAM the
3401 assembler syntax for an instruction operand X. X is an RTL
3404 CODE is a value that can be used to specify one of several ways
3405 of printing the operand. It is used when identical operands
3406 must be printed differently depending on the context. CODE
3407 comes from the `%' specification that was used to request
3408 printing of the operand. If the specification was just `%DIGIT'
3409 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3410 is the ASCII code for LTR.
3412 If X is a register, this macro should print the register's name.
3413 The names can be found in an array `reg_names' whose type is
3414 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3416 When the machine description has a specification `%PUNCT' (a `%'
3417 followed by a punctuation character), this macro is called with
3418 a null pointer for X and the punctuation character for CODE.
3420 The MIPS specific codes are:
3422 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
3423 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
3424 'd' output integer constant in decimal,
3425 'z' if the operand is 0, use $0 instead of normal operand.
3426 'D' print second register of double-word register operand.
3427 'L' print low-order register of double-word register operand.
3428 'M' print high-order register of double-word register operand.
3429 'C' print part of opcode for a branch condition.
3430 'N' print part of opcode for a branch condition, inverted.
3431 'S' X is CODE_LABEL, print with prefix of "LS" (for embedded switch).
3432 '(' Turn on .set noreorder
3433 ')' Turn on .set reorder
3434 '[' Turn on .set noat
3436 '<' Turn on .set nomacro
3437 '>' Turn on .set macro
3438 '{' Turn on .set volatile (not GAS)
3439 '}' Turn on .set novolatile (not GAS)
3440 '&' Turn on .set noreorder if filling delay slots
3441 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
3442 '!' Turn on .set nomacro if filling delay slots
3443 '#' Print nop if in a .set noreorder section.
3444 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3445 '@' Print the name of the assembler temporary register (at or $1).
3446 '.' Print the name of the register with a hard-wired zero (zero or $0).
3447 '^' Print the name of the pic call-through register (t9 or $25). */
3450 print_operand (file
, op
, letter
)
3451 FILE *file
; /* file to write to */
3452 rtx op
; /* operand to print */
3453 int letter
; /* %<letter> or 0 */
3455 register enum rtx_code code
;
3457 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3462 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3466 if (mips_branch_likely
)
3471 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3475 fputs (reg_names
[PIC_FUNCTION_ADDR_REGNUM
], file
);
3479 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3483 if (final_sequence
!= 0 && set_noreorder
++ == 0)
3484 fputs (".set\tnoreorder\n\t", file
);
3488 if (final_sequence
!= 0)
3490 if (set_noreorder
++ == 0)
3491 fputs (".set\tnoreorder\n\t", file
);
3493 if (set_nomacro
++ == 0)
3494 fputs (".set\tnomacro\n\t", file
);
3499 if (final_sequence
!= 0 && set_nomacro
++ == 0)
3500 fputs ("\n\t.set\tnomacro", file
);
3504 if (set_noreorder
!= 0)
3505 fputs ("\n\tnop", file
);
3507 else if (TARGET_STATS
)
3508 fputs ("\n\t#nop", file
);
3513 if (set_noreorder
++ == 0)
3514 fputs (".set\tnoreorder\n\t", file
);
3518 if (set_noreorder
== 0)
3519 error ("internal error: %%) found without a %%( in assembler pattern");
3521 else if (--set_noreorder
== 0)
3522 fputs ("\n\t.set\treorder", file
);
3527 if (set_noat
++ == 0)
3528 fputs (".set\tnoat\n\t", file
);
3533 error ("internal error: %%] found without a %%[ in assembler pattern");
3535 else if (--set_noat
== 0)
3536 fputs ("\n\t.set\tat", file
);
3541 if (set_nomacro
++ == 0)
3542 fputs (".set\tnomacro\n\t", file
);
3546 if (set_nomacro
== 0)
3547 error ("internal error: %%> found without a %%< in assembler pattern");
3549 else if (--set_nomacro
== 0)
3550 fputs ("\n\t.set\tmacro", file
);
3555 if (set_volatile
++ == 0)
3556 fprintf (file
, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS
) ? "" : "#");
3560 if (set_volatile
== 0)
3561 error ("internal error: %%} found without a %%{ in assembler pattern");
3563 else if (--set_volatile
== 0)
3564 fprintf (file
, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS
) ? "" : "#");
3573 error ("PRINT_OPERAND null pointer");
3577 code
= GET_CODE (op
);
3581 case EQ
: fputs ("eq", file
); break;
3582 case NE
: fputs ("ne", file
); break;
3583 case GT
: fputs ("gt", file
); break;
3584 case GE
: fputs ("ge", file
); break;
3585 case LT
: fputs ("lt", file
); break;
3586 case LE
: fputs ("le", file
); break;
3587 case GTU
: fputs ("gtu", file
); break;
3588 case GEU
: fputs ("geu", file
); break;
3589 case LTU
: fputs ("ltu", file
); break;
3590 case LEU
: fputs ("leu", file
); break;
3593 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%C");
3596 else if (letter
== 'N')
3599 case EQ
: fputs ("ne", file
); break;
3600 case NE
: fputs ("eq", file
); break;
3601 case GT
: fputs ("le", file
); break;
3602 case GE
: fputs ("lt", file
); break;
3603 case LT
: fputs ("ge", file
); break;
3604 case LE
: fputs ("gt", file
); break;
3605 case GTU
: fputs ("leu", file
); break;
3606 case GEU
: fputs ("ltu", file
); break;
3607 case LTU
: fputs ("geu", file
); break;
3608 case LEU
: fputs ("gtu", file
); break;
3611 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%N");
3614 else if (letter
== 'S')
3618 ASM_GENERATE_INTERNAL_LABEL (buffer
, "LS", CODE_LABEL_NUMBER (op
));
3619 assemble_name (file
, buffer
);
3622 else if (code
== REG
)
3624 register int regnum
= REGNO (op
);
3627 regnum
+= MOST_SIGNIFICANT_WORD
;
3629 else if (letter
== 'L')
3630 regnum
+= LEAST_SIGNIFICANT_WORD
;
3632 else if (letter
== 'D')
3635 fprintf (file
, "%s", reg_names
[regnum
]);
3638 else if (code
== MEM
)
3639 output_address (XEXP (op
, 0));
3641 else if (code
== CONST_DOUBLE
)
3646 REAL_VALUE_FROM_CONST_DOUBLE (d
, op
);
3647 REAL_VALUE_TO_DECIMAL (d
, "%.20e", s
);
3651 else if ((letter
== 'x') && (GET_CODE(op
) == CONST_INT
))
3652 fprintf (file
, "0x%04x", 0xffff & (INTVAL(op
)));
3654 else if ((letter
== 'X') && (GET_CODE(op
) == CONST_INT
))
3655 fprintf (file
, "0x%08x", INTVAL(op
));
3657 else if ((letter
== 'd') && (GET_CODE(op
) == CONST_INT
))
3658 fprintf (file
, "%d", (INTVAL(op
)));
3660 else if (letter
== 'z'
3661 && (GET_CODE (op
) == CONST_INT
)
3662 && INTVAL (op
) == 0)
3663 fputs (reg_names
[GP_REG_FIRST
], file
);
3665 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3666 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter
);
3669 output_addr_const (file
, op
);
3673 /* A C compound statement to output to stdio stream STREAM the
3674 assembler syntax for an instruction operand that is a memory
3675 reference whose address is ADDR. ADDR is an RTL expression.
3677 On some machines, the syntax for a symbolic address depends on
3678 the section that the address refers to. On these machines,
3679 define the macro `ENCODE_SECTION_INFO' to store the information
3680 into the `symbol_ref', and then check for it here. */
3683 print_operand_address (file
, addr
)
3688 error ("PRINT_OPERAND_ADDRESS, null pointer");
3691 switch (GET_CODE (addr
))
3694 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #1");
3698 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3699 abort_with_insn (addr
, "Arg pointer not eliminated.");
3701 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
3706 register rtx reg
= (rtx
)0;
3707 register rtx offset
= (rtx
)0;
3708 register rtx arg0
= XEXP (addr
, 0);
3709 register rtx arg1
= XEXP (addr
, 1);
3711 if (GET_CODE (arg0
) == REG
)
3715 if (GET_CODE (offset
) == REG
)
3716 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
3718 else if (GET_CODE (arg1
) == REG
)
3723 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
3725 output_addr_const (file
, addr
);
3729 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3731 if (!CONSTANT_P (offset
))
3732 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #2");
3734 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3735 abort_with_insn (addr
, "Arg pointer not eliminated.");
3737 output_addr_const (file
, offset
);
3738 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3746 output_addr_const (file
, addr
);
3752 /* If optimizing for the global pointer, keep track of all of
3753 the externs, so that at the end of the file, we can emit
3754 the appropriate .extern declaration for them, before writing
3755 out the text section. We assume that all names passed to
3756 us are in the permanent obstack, so that they will be valid
3757 at the end of the compilation.
3759 If we have -G 0, or the extern size is unknown, don't bother
3760 emitting the .externs. */
3763 mips_output_external (file
, decl
, name
)
3768 register struct extern_list
*p
;
3772 && ((TREE_CODE (decl
)) != FUNCTION_DECL
)
3773 && ((len
= int_size_in_bytes (TREE_TYPE (decl
))) > 0))
3775 p
= (struct extern_list
*)permalloc ((long) sizeof (struct extern_list
));
3776 p
->next
= extern_head
;
3782 #ifdef ASM_OUTPUT_UNDEF_FUNCTION
3783 if (TREE_CODE (decl
) == FUNCTION_DECL
)
3785 p
= (struct extern_list
*)permalloc ((long) sizeof (struct extern_list
));
3786 p
->next
= extern_head
;
3796 #ifdef ASM_OUTPUT_UNDEF_FUNCTION
3798 mips_output_external_libcall (file
, name
)
3802 register struct extern_list
*p
;
3804 p
= (struct extern_list
*)permalloc ((long) sizeof (struct extern_list
));
3805 p
->next
= extern_head
;
3815 /* Compute a string to use as a temporary file name. */
3817 /* On MSDOS, write temp files in current dir
3818 because there's no place else we can expect to use. */
3821 #define P_tmpdir "./"
3829 char *base
= getenv ("TMPDIR");
3832 if (base
== (char *)0)
3835 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
3839 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
3845 len
= strlen (base
);
3846 /* temp_filename is global, so we must use malloc, not alloca. */
3847 temp_filename
= (char *) xmalloc (len
+ sizeof("/ctXXXXXX"));
3848 strcpy (temp_filename
, base
);
3849 if (len
> 0 && temp_filename
[len
-1] != '/')
3850 temp_filename
[len
++] = '/';
3852 strcpy (temp_filename
+ len
, "ctXXXXXX");
3853 mktemp (temp_filename
);
3855 stream
= fopen (temp_filename
, "w+");
3857 pfatal_with_name (temp_filename
);
3860 /* In MSDOS, we cannot unlink the temporary file until we are finished using
3861 it. Otherwise, we delete it now, so that it will be gone even if the
3862 compiler happens to crash. */
3863 unlink (temp_filename
);
3869 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out
3870 for .file's that start within a function. If we are smuggling stabs, try to
3871 put out a MIPS ECOFF file and a stab. */
3874 mips_output_filename (stream
, name
)
3878 static int first_time
= TRUE
;
3879 char ltext_label_name
[100];
3885 current_function_file
= name
;
3886 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
3887 output_quoted_string (stream
, name
);
3888 fprintf (stream
, "\n");
3889 /* This tells mips-tfile that stabs will follow. */
3890 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3891 fprintf (stream
, "\t#@stabs\n");
3894 else if (write_symbols
== DBX_DEBUG
)
3896 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
3897 fprintf (stream
, "%s ", ASM_STABS_OP
);
3898 output_quoted_string (stream
, name
);
3899 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
3902 else if (name
!= current_function_file
3903 && strcmp (name
, current_function_file
) != 0)
3905 if (inside_function
&& !TARGET_GAS
)
3907 if (!file_in_function_warning
)
3909 file_in_function_warning
= TRUE
;
3910 ignore_line_number
= TRUE
;
3911 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line");
3914 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
3920 current_function_file
= name
;
3921 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
3923 output_quoted_string (stream
, name
);
3924 fprintf (stream
, "\n");
3929 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
3930 as well as a .loc, since it is possible that MIPS ECOFF might not be
3931 able to represent the location for inlines that come from a different
3935 mips_output_lineno (stream
, line
)
3939 if (write_symbols
== DBX_DEBUG
)
3942 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3943 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
3948 fprintf (stream
, "\n\t%s.loc\t%d %d\n",
3949 (ignore_line_number
) ? "#" : "",
3950 num_source_filenames
, line
);
3952 LABEL_AFTER_LOC (stream
);
3957 /* If defined, a C statement to be executed just prior to the
3958 output of assembler code for INSN, to modify the extracted
3959 operands so they will be output differently.
3961 Here the argument OPVEC is the vector containing the operands
3962 extracted from INSN, and NOPERANDS is the number of elements of
3963 the vector which contain meaningful data for this insn. The
3964 contents of this vector are what will be used to convert the
3965 insn template into assembler code, so you can change the
3966 assembler output by changing the contents of the vector.
3968 We use it to check if the current insn needs a nop in front of it
3969 because of load delays, and also to update the delay slot
3972 /* ??? There is no real need for this function, because it never actually
3973 emits a NOP anymore. */
3976 final_prescan_insn (insn
, opvec
, noperands
)
3981 if (dslots_number_nops
> 0)
3983 rtx pattern
= PATTERN (insn
);
3984 int length
= get_attr_length (insn
);
3986 /* Do we need to emit a NOP? */
3988 || (mips_load_reg
!= (rtx
)0 && reg_mentioned_p (mips_load_reg
, pattern
))
3989 || (mips_load_reg2
!= (rtx
)0 && reg_mentioned_p (mips_load_reg2
, pattern
))
3990 || (mips_load_reg3
!= (rtx
)0 && reg_mentioned_p (mips_load_reg3
, pattern
))
3991 || (mips_load_reg4
!= (rtx
)0 && reg_mentioned_p (mips_load_reg4
, pattern
)))
3992 fputs ("\t#nop\n", asm_out_file
);
3995 dslots_load_filled
++;
3997 while (--dslots_number_nops
> 0)
3998 fputs ("\t#nop\n", asm_out_file
);
4000 mips_load_reg
= (rtx
)0;
4001 mips_load_reg2
= (rtx
)0;
4002 mips_load_reg3
= (rtx
)0;
4003 mips_load_reg4
= (rtx
)0;
4008 enum rtx_code code
= GET_CODE (insn
);
4009 if (code
== JUMP_INSN
|| code
== CALL_INSN
)
4010 dslots_jump_total
++;
4015 /* Output at beginning of assembler file.
4016 If we are optimizing to use the global pointer, create a temporary
4017 file to hold all of the text stuff, and write it out to the end.
4018 This is needed because the MIPS assembler is evidently one pass,
4019 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata
4020 declaration when the code is processed, it generates a two
4021 instruction sequence. */
4024 mips_asm_file_start (stream
)
4027 ASM_OUTPUT_SOURCE_FILENAME (stream
, main_input_filename
);
4029 /* Versions of the MIPS assembler before 2.20 generate errors
4030 if a branch inside of a .set noreorder section jumps to a
4031 label outside of the .set noreorder section. Revision 2.20
4032 just set nobopt silently rather than fixing the bug. */
4034 if (TARGET_MIPS_AS
&& optimize
&& flag_delayed_branch
)
4035 fprintf (stream
, "\t.set\tnobopt\n");
4037 /* Generate the pseudo ops that System V.4 wants. */
4038 #ifndef ABICALLS_ASM_OP
4039 #define ABICALLS_ASM_OP ".abicalls"
4041 if (TARGET_ABICALLS
)
4042 /* ??? but do not want this (or want pic0) if -non-shared? */
4043 fprintf (stream
, "\t%s\n", ABICALLS_ASM_OP
);
4045 /* This code exists so that we can put all externs before all symbol
4046 references. This is necessary for the assembler's global pointer
4047 optimizations to work. */
4048 /* ??? Current versions of gas do not require that externs occur before
4049 symbol references. This means that this code is unnecessary when
4050 gas is being used. This gas feature hasn't been well tested as yet
4054 asm_out_data_file
= stream
;
4055 asm_out_text_file
= make_temp_file ();
4058 asm_out_data_file
= asm_out_text_file
= stream
;
4060 print_options (stream
);
4064 /* If we are optimizing the global pointer, emit the text section now
4065 and any small externs which did not have .comm, etc that are
4066 needed. Also, give a warning if the data area is more than 32K and
4067 -pic because 3 instructions are needed to reference the data
4071 mips_asm_file_end (file
)
4076 struct extern_list
*p
;
4080 HALF_PIC_FINISH (file
);
4086 for (p
= extern_head
; p
!= 0; p
= p
->next
)
4088 name_tree
= get_identifier (p
->name
);
4090 /* Positively ensure only one .extern for any given symbol. */
4091 if (! TREE_ASM_WRITTEN (name_tree
))
4093 TREE_ASM_WRITTEN (name_tree
) = 1;
4094 #ifdef ASM_OUTPUT_UNDEF_FUNCTION
4096 ASM_OUTPUT_UNDEF_FUNCTION (file
, p
->name
);
4100 fputs ("\t.extern\t", file
);
4101 assemble_name (file
, p
->name
);
4102 fprintf (file
, ", %d\n", p
->size
);
4110 fprintf (file
, "\n\t.text\n");
4111 rewind (asm_out_text_file
);
4112 if (ferror (asm_out_text_file
))
4113 fatal_io_error (temp_filename
);
4115 while ((len
= fread (buffer
, 1, sizeof (buffer
), asm_out_text_file
)) > 0)
4116 if (fwrite (buffer
, 1, len
, file
) != len
)
4117 pfatal_with_name (asm_file_name
);
4120 pfatal_with_name (temp_filename
);
4122 if (fclose (asm_out_text_file
) != 0)
4123 pfatal_with_name (temp_filename
);
4126 unlink (temp_filename
);
4132 /* Emit either a label, .comm, or .lcomm directive, and mark
4133 that the symbol is used, so that we don't emit an .extern
4134 for it in mips_asm_file_end. */
4137 mips_declare_object (stream
, name
, init_string
, final_string
, size
)
4144 fputs (init_string
, stream
); /* "", "\t.comm\t", or "\t.lcomm\t" */
4145 assemble_name (stream
, name
);
4146 fprintf (stream
, final_string
, size
); /* ":\n", ",%u\n", ",%u\n" */
4150 tree name_tree
= get_identifier (name
);
4151 TREE_ASM_WRITTEN (name_tree
) = 1;
4156 /* Output a double precision value to the assembler. If both the
4157 host and target are IEEE, emit the values in hex. */
4160 mips_output_double (stream
, value
)
4162 REAL_VALUE_TYPE value
;
4164 #ifdef REAL_VALUE_TO_TARGET_DOUBLE
4166 REAL_VALUE_TO_TARGET_DOUBLE (value
, value_long
);
4168 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n",
4169 value_long
[0], value
, value_long
[1]);
4171 fprintf (stream
, "\t.double\t%.20g\n", value
);
4176 /* Output a single precision value to the assembler. If both the
4177 host and target are IEEE, emit the values in hex. */
4180 mips_output_float (stream
, value
)
4182 REAL_VALUE_TYPE value
;
4184 #ifdef REAL_VALUE_TO_TARGET_SINGLE
4186 REAL_VALUE_TO_TARGET_SINGLE (value
, value_long
);
4188 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long
, value
);
4190 fprintf (stream
, "\t.float\t%.12g\n", value
);
4195 /* Return TRUE if any register used in the epilogue is used. This to insure
4196 any insn put into the epilogue delay slots is safe. */
4199 epilogue_reg_mentioned_p (insn
)
4204 register enum rtx_code code
;
4210 if (GET_CODE (insn
) == LABEL_REF
)
4213 code
= GET_CODE (insn
);
4217 regno
= REGNO (insn
);
4218 if (regno
== STACK_POINTER_REGNUM
)
4221 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
4224 if (!call_used_regs
[regno
])
4227 if (regno
!= MIPS_TEMP1_REGNUM
&& regno
!= MIPS_TEMP2_REGNUM
)
4230 if (!current_frame_info
.initialized
)
4231 compute_frame_size (get_frame_size ());
4233 return (current_frame_info
.total_size
>= 32768);
4243 fmt
= GET_RTX_FORMAT (code
);
4244 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4249 for (j
= XVECLEN (insn
, i
) - 1; j
>= 0; j
--)
4250 if (epilogue_reg_mentioned_p (XVECEXP (insn
, i
, j
)))
4253 else if (fmt
[i
] == 'e' && epilogue_reg_mentioned_p (XEXP (insn
, i
)))
4261 /* When generating embedded PIC code we may need to get the address of
4262 the current function. We will need it if we take the address of
4263 any symbol in the .text section. */
4266 mips_finalize_pic ()
4270 if (! TARGET_EMBEDDED_PIC
)
4272 if (embedded_pic_fnaddr_rtx
== NULL
)
4277 emit_insn (gen_get_fnaddr (embedded_pic_fnaddr_rtx
,
4278 XEXP (DECL_RTL (current_function_decl
), 0)));
4280 seq
= gen_sequence ();
4282 emit_insn_after (seq
, get_insns ());
4284 embedded_pic_fnaddr_rtx
= NULL
;
4288 /* Return the bytes needed to compute the frame pointer from the current
4291 Mips stack frames look like:
4293 Before call After call
4294 +-----------------------+ +-----------------------+
4297 | caller's temps. | | caller's temps. |
4299 +-----------------------+ +-----------------------+
4301 | arguments on stack. | | arguments on stack. |
4303 +-----------------------+ +-----------------------+
4304 | 4 words to save | | 4 words to save |
4305 | arguments passed | | arguments passed |
4306 | in registers, even | | in registers, even |
4307 SP->| if not passed. | VFP->| if not passed. |
4308 +-----------------------+ +-----------------------+
4310 | fp register save |
4312 +-----------------------+
4314 | gp register save |
4316 +-----------------------+
4320 +-----------------------+
4322 | alloca allocations |
4324 +-----------------------+
4326 | GP save for V.4 abi |
4328 +-----------------------+
4330 | arguments on stack |
4332 +-----------------------+
4334 | arguments passed |
4335 | in registers, even |
4336 low SP->| if not passed. |
4337 memory +-----------------------+
4342 compute_frame_size (size
)
4343 int size
; /* # of var. bytes allocated */
4346 long total_size
; /* # bytes that the entire frame takes up */
4347 long var_size
; /* # bytes that variables take up */
4348 long args_size
; /* # bytes that outgoing arguments take up */
4349 long extra_size
; /* # extra bytes */
4350 long gp_reg_rounded
; /* # bytes needed to store gp after rounding */
4351 long gp_reg_size
; /* # bytes needed to store gp regs */
4352 long fp_reg_size
; /* # bytes needed to store fp regs */
4353 long mask
; /* mask of saved gp registers */
4354 long fmask
; /* mask of saved fp registers */
4355 int fp_inc
; /* 1 or 2 depending on the size of fp regs */
4356 long fp_bits
; /* bitmask to use for each fp register */
4362 extra_size
= MIPS_STACK_ALIGN (((TARGET_ABICALLS
) ? UNITS_PER_WORD
: 0));
4363 var_size
= MIPS_STACK_ALIGN (size
);
4364 args_size
= MIPS_STACK_ALIGN (current_function_outgoing_args_size
);
4366 /* The MIPS 3.0 linker does not like functions that dynamically
4367 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
4368 looks like we are trying to create a second frame pointer to the
4369 function, so allocate some stack space to make it happy. */
4371 if (args_size
== 0 && current_function_calls_alloca
)
4372 args_size
= 4*UNITS_PER_WORD
;
4374 total_size
= var_size
+ args_size
+ extra_size
;
4376 /* Calculate space needed for gp registers. */
4377 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
4379 if (MUST_SAVE_REGISTER (regno
))
4381 gp_reg_size
+= UNITS_PER_WORD
;
4382 mask
|= 1L << (regno
- GP_REG_FIRST
);
4386 /* Calculate space needed for fp registers. */
4398 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
+= fp_inc
)
4400 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
4402 fp_reg_size
+= fp_inc
* UNITS_PER_FPREG
;
4403 fmask
|= fp_bits
<< (regno
- FP_REG_FIRST
);
4407 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
4408 total_size
+= gp_reg_rounded
+ fp_reg_size
;
4410 if (total_size
== extra_size
)
4411 total_size
= extra_size
= 0;
4412 else if (TARGET_ABICALLS
)
4414 /* Add the context-pointer to the saved registers. */
4415 gp_reg_size
+= UNITS_PER_WORD
;
4416 mask
|= 1L << (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
);
4417 total_size
-= gp_reg_rounded
;
4418 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
4419 total_size
+= gp_reg_rounded
;
4422 /* Save other computed information. */
4423 current_frame_info
.total_size
= total_size
;
4424 current_frame_info
.var_size
= var_size
;
4425 current_frame_info
.args_size
= args_size
;
4426 current_frame_info
.extra_size
= extra_size
;
4427 current_frame_info
.gp_reg_size
= gp_reg_size
;
4428 current_frame_info
.fp_reg_size
= fp_reg_size
;
4429 current_frame_info
.mask
= mask
;
4430 current_frame_info
.fmask
= fmask
;
4431 current_frame_info
.initialized
= reload_completed
;
4432 current_frame_info
.num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
4433 current_frame_info
.num_fp
= fp_reg_size
/ (fp_inc
* UNITS_PER_FPREG
);
4437 unsigned long offset
= args_size
+ extra_size
+ var_size
4438 + gp_reg_size
- UNITS_PER_WORD
;
4439 current_frame_info
.gp_sp_offset
= offset
;
4440 current_frame_info
.gp_save_offset
= offset
- total_size
;
4444 current_frame_info
.gp_sp_offset
= 0;
4445 current_frame_info
.gp_save_offset
= 0;
4451 unsigned long offset
= (args_size
+ extra_size
+ var_size
4452 + gp_reg_rounded
+ fp_reg_size
4453 - fp_inc
* UNITS_PER_FPREG
);
4454 current_frame_info
.fp_sp_offset
= offset
;
4455 current_frame_info
.fp_save_offset
= offset
- total_size
+ UNITS_PER_WORD
;
4459 current_frame_info
.fp_sp_offset
= 0;
4460 current_frame_info
.fp_save_offset
= 0;
4463 /* Ok, we're done. */
4468 /* Common code to emit the insns (or to write the instructions to a file)
4469 to save/restore registers.
4471 Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg)
4472 is not modified within save_restore_insns. */
4474 #define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0)
4477 save_restore_insns (store_p
, large_reg
, large_offset
, file
)
4478 int store_p
; /* true if this is prologue */
4479 rtx large_reg
; /* register holding large offset constant or NULL */
4480 long large_offset
; /* large constant offset value */
4481 FILE *file
; /* file to write instructions to instead of making RTL */
4483 long mask
= current_frame_info
.mask
;
4484 long fmask
= current_frame_info
.fmask
;
4492 if (frame_pointer_needed
&& !BITSET_P (mask
, FRAME_POINTER_REGNUM
- GP_REG_FIRST
))
4495 if (mask
== 0 && fmask
== 0)
4498 /* Save registers starting from high to low. The debuggers prefer
4499 at least the return register be stored at func+4, and also it
4500 allows us not to need a nop in the epilog if at least one
4501 register is reloaded in addition to return address. */
4503 /* Save GP registers if needed. */
4506 /* Pick which pointer to use as a base register. For small
4507 frames, just use the stack pointer. Otherwise, use a
4508 temporary register. Save 2 cycles if the save area is near
4509 the end of a large frame, by reusing the constant created in
4510 the prologue/epilogue to adjust the stack frame. */
4512 gp_offset
= current_frame_info
.gp_sp_offset
;
4513 end_offset
= gp_offset
- (current_frame_info
.gp_reg_size
- UNITS_PER_WORD
);
4515 if (gp_offset
< 0 || end_offset
< 0)
4516 fatal ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
4517 gp_offset
, end_offset
);
4519 else if (gp_offset
< 32768)
4521 base_reg_rtx
= stack_pointer_rtx
;
4525 else if (large_reg
!= (rtx
)0
4526 && (((unsigned long)(large_offset
- gp_offset
)) < 32768)
4527 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4529 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4530 base_offset
= large_offset
;
4531 if (file
== (FILE *)0)
4534 emit_insn (gen_adddi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4536 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4539 fprintf (file
, "\t%s\t%s,%s,%s\n",
4540 TARGET_LONG64
? "daddu" : "addu",
4541 reg_names
[MIPS_TEMP2_REGNUM
],
4542 reg_names
[REGNO (large_reg
)],
4543 reg_names
[STACK_POINTER_REGNUM
]);
4548 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4549 base_offset
= gp_offset
;
4550 if (file
== (FILE *)0)
4552 emit_move_insn (base_reg_rtx
, GEN_INT (gp_offset
));
4554 emit_insn (gen_adddi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4556 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4559 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n",
4560 reg_names
[MIPS_TEMP2_REGNUM
],
4563 TARGET_LONG64
? "daddu" : "addu",
4564 reg_names
[MIPS_TEMP2_REGNUM
],
4565 reg_names
[MIPS_TEMP2_REGNUM
],
4566 reg_names
[STACK_POINTER_REGNUM
]);
4569 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
4571 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
4573 if (file
== (FILE *)0)
4575 rtx reg_rtx
= gen_rtx (REG
, word_mode
, regno
);
4576 rtx mem_rtx
= gen_rtx (MEM
, word_mode
,
4577 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4578 GEN_INT (gp_offset
- base_offset
)));
4581 emit_move_insn (mem_rtx
, reg_rtx
);
4582 else if (!TARGET_ABICALLS
4583 || regno
!= (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
))
4584 emit_move_insn (reg_rtx
, mem_rtx
);
4588 if (store_p
|| !TARGET_ABICALLS
4589 || regno
!= (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
))
4590 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4592 ? (store_p
) ? "sd" : "ld"
4593 : (store_p
) ? "sw" : "lw"),
4595 gp_offset
- base_offset
,
4596 reg_names
[REGNO(base_reg_rtx
)]);
4599 gp_offset
-= UNITS_PER_WORD
;
4605 base_reg_rtx
= (rtx
)0; /* Make sure these are initialzed */
4609 /* Save floating point registers if needed. */
4612 int fp_inc
= (TARGET_FLOAT64
) ? 1 : 2;
4613 int fp_size
= fp_inc
* UNITS_PER_FPREG
;
4615 /* Pick which pointer to use as a base register. */
4616 fp_offset
= current_frame_info
.fp_sp_offset
;
4617 end_offset
= fp_offset
- (current_frame_info
.fp_reg_size
- fp_size
);
4619 if (fp_offset
< 0 || end_offset
< 0)
4620 fatal ("fp_offset (%ld) or end_offset (%ld) is less than zero.",
4621 fp_offset
, end_offset
);
4623 else if (fp_offset
< 32768)
4625 base_reg_rtx
= stack_pointer_rtx
;
4629 else if (base_reg_rtx
!= (rtx
)0
4630 && (((unsigned long)(base_offset
- fp_offset
)) < 32768)
4631 && (((unsigned long)(base_offset
- end_offset
)) < 32768))
4633 ; /* already set up for gp registers above */
4636 else if (large_reg
!= (rtx
)0
4637 && (((unsigned long)(large_offset
- fp_offset
)) < 32768)
4638 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4640 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4641 base_offset
= large_offset
;
4642 if (file
== (FILE *)0)
4645 emit_insn (gen_adddi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4647 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4650 fprintf (file
, "\t%s\t%s,%s,%s\n",
4651 TARGET_LONG64
? "daddu" : "addu",
4652 reg_names
[MIPS_TEMP2_REGNUM
],
4653 reg_names
[REGNO (large_reg
)],
4654 reg_names
[STACK_POINTER_REGNUM
]);
4659 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4660 base_offset
= fp_offset
;
4661 if (file
== (FILE *)0)
4663 emit_move_insn (base_reg_rtx
, GEN_INT (fp_offset
));
4665 emit_insn (gen_adddi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4667 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4670 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\t%s\t%s,%s,%s\n",
4671 reg_names
[MIPS_TEMP2_REGNUM
],
4674 TARGET_LONG64
? "daddu" : "addu",
4675 reg_names
[MIPS_TEMP2_REGNUM
],
4676 reg_names
[MIPS_TEMP2_REGNUM
],
4677 reg_names
[STACK_POINTER_REGNUM
]);
4680 for (regno
= FP_REG_LAST
-1; regno
>= FP_REG_FIRST
; regno
-= fp_inc
)
4682 if (BITSET_P (fmask
, regno
- FP_REG_FIRST
))
4684 if (file
== (FILE *)0)
4686 rtx reg_rtx
= gen_rtx (REG
, DFmode
, regno
);
4687 rtx mem_rtx
= gen_rtx (MEM
, DFmode
,
4688 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4689 GEN_INT (fp_offset
- base_offset
)));
4692 emit_move_insn (mem_rtx
, reg_rtx
);
4694 emit_move_insn (reg_rtx
, mem_rtx
);
4697 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4698 (store_p
) ? "s.d" : "l.d",
4700 fp_offset
- base_offset
,
4701 reg_names
[REGNO(base_reg_rtx
)]);
4704 fp_offset
-= fp_size
;
4711 /* Set up the stack and frame (if desired) for the function. */
4714 function_prologue (file
, size
)
4718 long tsize
= current_frame_info
.total_size
;
4720 ASM_OUTPUT_SOURCE_FILENAME (file
, DECL_SOURCE_FILE (current_function_decl
));
4722 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
4723 ASM_OUTPUT_SOURCE_LINE (file
, DECL_SOURCE_LINE (current_function_decl
));
4725 inside_function
= 1;
4726 fputs ("\t.ent\t", file
);
4727 assemble_name (file
, current_function_name
);
4730 assemble_name (file
, current_function_name
);
4731 fputs (":\n", file
);
4733 fprintf (file
, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args= %d, extra= %d\n",
4734 reg_names
[ (frame_pointer_needed
) ? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
],
4736 reg_names
[31 + GP_REG_FIRST
],
4737 current_frame_info
.var_size
,
4738 current_frame_info
.num_gp
,
4739 current_frame_info
.num_fp
,
4740 current_function_outgoing_args_size
,
4741 current_frame_info
.extra_size
);
4743 fprintf (file
, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n",
4744 current_frame_info
.mask
,
4745 current_frame_info
.gp_save_offset
,
4746 current_frame_info
.fmask
,
4747 current_frame_info
.fp_save_offset
);
4749 if (TARGET_ABICALLS
)
4751 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4753 fprintf (file
, "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
4754 reg_names
[PIC_FUNCTION_ADDR_REGNUM
]);
4757 fprintf (file
, "\t%s\t%s,%s,%d\n",
4758 (TARGET_LONG64
? "dsubu" : "subu"),
4759 sp_str
, sp_str
, tsize
);
4760 fprintf (file
, "\t.cprestore %d\n", current_frame_info
.args_size
);
4766 /* Expand the prologue into a bunch of separate insns. */
4769 mips_expand_prologue ()
4773 rtx tmp_rtx
= (rtx
)0;
4774 char *arg_name
= (char *)0;
4775 tree fndecl
= current_function_decl
;
4776 tree fntype
= TREE_TYPE (fndecl
);
4777 tree fnargs
= (TREE_CODE (fntype
) != METHOD_TYPE
)
4778 ? DECL_ARGUMENTS (fndecl
)
4784 CUMULATIVE_ARGS args_so_far
;
4786 /* If struct value address is treated as the first argument, make it so. */
4787 if (aggregate_value_p (DECL_RESULT (fndecl
))
4788 && ! current_function_returns_pcc_struct
4789 && struct_value_incoming_rtx
== 0)
4791 tree type
= build_pointer_type (fntype
);
4792 tree function_result_decl
= build_decl (PARM_DECL
, NULL_TREE
, type
);
4793 DECL_ARG_TYPE (function_result_decl
) = type
;
4794 TREE_CHAIN (function_result_decl
) = fnargs
;
4795 fnargs
= function_result_decl
;
4798 /* Determine the last argument, and get its name. */
4800 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, (rtx
)0);
4801 regno
= GP_ARG_FIRST
;
4803 for (cur_arg
= fnargs
; cur_arg
!= (tree
)0; cur_arg
= next_arg
)
4805 tree type
= DECL_ARG_TYPE (cur_arg
);
4806 enum machine_mode passed_mode
= TYPE_MODE (type
);
4807 rtx entry_parm
= FUNCTION_ARG (args_so_far
,
4809 DECL_ARG_TYPE (cur_arg
),
4816 /* passed in a register, so will get homed automatically */
4817 if (GET_MODE (entry_parm
) == BLKmode
)
4818 words
= (int_size_in_bytes (type
) + 3) / 4;
4820 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
4822 regno
= REGNO (entry_parm
) + words
- 1;
4826 regno
= GP_ARG_LAST
+1;
4830 FUNCTION_ARG_ADVANCE (args_so_far
,
4832 DECL_ARG_TYPE (cur_arg
),
4835 next_arg
= TREE_CHAIN (cur_arg
);
4836 if (next_arg
== (tree
)0)
4838 if (DECL_NAME (cur_arg
))
4839 arg_name
= IDENTIFIER_POINTER (DECL_NAME (cur_arg
));
4845 /* In order to pass small structures by value in registers
4846 compatibly with the MIPS compiler, we need to shift the value
4847 into the high part of the register. Function_arg has encoded a
4848 PARALLEL rtx, holding a vector of adjustments to be made as the
4849 next_arg_reg variable, so we split up the insns, and emit them
4852 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
4853 if (next_arg_reg
!= (rtx
)0 && GET_CODE (next_arg_reg
) == PARALLEL
)
4855 rtvec adjust
= XVEC (next_arg_reg
, 0);
4856 int num
= GET_NUM_ELEM (adjust
);
4858 for (i
= 0; i
< num
; i
++)
4860 rtx pattern
= RTVEC_ELT (adjust
, i
);
4861 if (GET_CODE (pattern
) != SET
4862 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
4863 abort_with_insn (pattern
, "Insn is not a shift");
4865 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
4866 emit_insn (pattern
);
4870 tsize
= compute_frame_size (get_frame_size ());
4872 /* If this function is a varargs function, store any registers that
4873 would normally hold arguments ($4 - $7) on the stack. */
4874 if ((TYPE_ARG_TYPES (fntype
) != 0
4875 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
))) != void_type_node
))
4876 || (arg_name
!= (char *)0
4877 && ((arg_name
[0] == '_' && strcmp (arg_name
, "__builtin_va_alist") == 0)
4878 || (arg_name
[0] == 'v' && strcmp (arg_name
, "va_alist") == 0))))
4880 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
4881 rtx ptr
= stack_pointer_rtx
;
4883 /* If we are doing svr4-abi, sp has already been decremented by tsize. */
4884 if (TARGET_ABICALLS
)
4887 for (; regno
<= GP_ARG_LAST
; regno
++)
4890 ptr
= gen_rtx (PLUS
, Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
4891 emit_move_insn (gen_rtx (MEM
, word_mode
, ptr
),
4892 gen_rtx (REG
, word_mode
, regno
));
4893 offset
+= UNITS_PER_WORD
;
4899 rtx tsize_rtx
= GEN_INT (tsize
);
4901 /* If we are doing svr4-abi, sp move is done by function_prologue. */
4902 if (!TARGET_ABICALLS
)
4906 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
4907 emit_move_insn (tmp_rtx
, tsize_rtx
);
4908 tsize_rtx
= tmp_rtx
;
4912 emit_insn (gen_subdi3 (stack_pointer_rtx
, stack_pointer_rtx
,
4915 emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
4919 save_restore_insns (TRUE
, tmp_rtx
, tsize
, (FILE *)0);
4921 if (frame_pointer_needed
)
4924 emit_insn (gen_movdi (frame_pointer_rtx
, stack_pointer_rtx
));
4926 emit_insn (gen_movsi (frame_pointer_rtx
, stack_pointer_rtx
));
4930 /* If we are profiling, make sure no instructions are scheduled before
4931 the call to mcount. */
4933 if (profile_flag
|| profile_block_flag
)
4934 emit_insn (gen_blockage ());
4938 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */
4940 #define RA_MASK ((long) 0x80000000) /* 1 << 31 */
4941 #define PIC_OFFSET_TABLE_MASK (1 << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))
4944 function_epilogue (file
, size
)
4949 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4950 char *t1_str
= reg_names
[MIPS_TEMP1_REGNUM
];
4951 rtx epilogue_delay
= current_function_epilogue_delay_list
;
4952 int noreorder
= (epilogue_delay
!= 0);
4953 int noepilogue
= FALSE
;
4954 int load_nop
= FALSE
;
4956 rtx tmp_rtx
= (rtx
)0;
4960 /* The epilogue does not depend on any registers, but the stack
4961 registers, so we assume that if we have 1 pending nop, it can be
4962 ignored, and 2 it must be filled (2 nops occur for integer
4963 multiply and divide). */
4965 if (dslots_number_nops
> 0)
4967 if (dslots_number_nops
== 1)
4969 dslots_number_nops
= 0;
4970 dslots_load_filled
++;
4974 while (--dslots_number_nops
> 0)
4975 fputs ("\t#nop\n", asm_out_file
);
4982 fputs ("\t.set\tat\n", file
);
4983 error ("internal gcc error: .set noat left on in epilogue");
4986 if (set_nomacro
!= 0)
4989 fputs ("\t.set\tmacro\n", file
);
4990 error ("internal gcc error: .set nomacro left on in epilogue");
4993 if (set_noreorder
!= 0)
4996 fputs ("\t.set\treorder\n", file
);
4997 error ("internal gcc error: .set noreorder left on in epilogue");
5000 if (set_volatile
!= 0)
5003 fprintf (file
, "\t%s.set\tnovolatile\n", (TARGET_MIPS_AS
) ? "" : "#");
5004 error ("internal gcc error: .set volatile left on in epilogue");
5007 size
= MIPS_STACK_ALIGN (size
);
5008 tsize
= (!current_frame_info
.initialized
)
5009 ? compute_frame_size (size
)
5010 : current_frame_info
.total_size
;
5012 if (tsize
== 0 && epilogue_delay
== 0)
5014 rtx insn
= get_last_insn ();
5016 /* If the last insn was a BARRIER, we don't have to write any code
5017 because a jump (aka return) was put there. */
5018 if (GET_CODE (insn
) == NOTE
)
5019 insn
= prev_nonnote_insn (insn
);
5020 if (insn
&& GET_CODE (insn
) == BARRIER
)
5028 /* In the reload sequence, we don't need to fill the load delay
5029 slots for most of the loads, also see if we can fill the final
5030 delay slot if not otherwise filled by the reload sequence. */
5033 fprintf (file
, "\t.set\tnoreorder\n");
5037 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str
, (long)tsize
, (long)tsize
);
5038 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
5041 if (frame_pointer_needed
)
5042 fprintf (file
, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
5043 sp_str
, reg_names
[FRAME_POINTER_REGNUM
]);
5045 save_restore_insns (FALSE
, tmp_rtx
, tsize
, file
);
5047 load_only_r31
= (((current_frame_info
.mask
5048 & ~ (TARGET_ABICALLS
? PIC_OFFSET_TABLE_MASK
: 0))
5050 && current_frame_info
.fmask
== 0);
5054 /* If the only register saved is the return address, we need a
5055 nop, unless we have an instruction to put into it. Otherwise
5056 we don't since reloading multiple registers doesn't reference
5057 the register being loaded. */
5062 final_scan_insn (XEXP (epilogue_delay
, 0),
5066 1); /* nopeepholes */
5069 fprintf (file
, "\tnop\n");
5074 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
5077 fprintf (file
, "\t%s\t%s,%s,%s\n",
5078 TARGET_LONG64
? "daddu" : "addu",
5079 sp_str
, sp_str
, t1_str
);
5082 fprintf (file
, "\t%s\t%s,%s,%d\n",
5083 TARGET_LONG64
? "daddu" : "addu",
5084 sp_str
, sp_str
, tsize
);
5086 else if (!load_only_r31
&& epilogue_delay
!= 0)
5087 final_scan_insn (XEXP (epilogue_delay
, 0),
5091 1); /* nopeepholes */
5093 fprintf (file
, "\t.set\treorder\n");
5099 fprintf (file
, "\t%s\t%s,%s,%s\n",
5100 TARGET_LONG64
? "daddu" : "addu",
5101 sp_str
, sp_str
, t1_str
);
5104 fprintf (file
, "\t%s\t%s,%s,%d\n",
5105 TARGET_LONG64
? "daddu" : "addu",
5106 sp_str
, sp_str
, tsize
);
5108 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
5112 fputs ("\t.end\t", file
);
5113 assemble_name (file
, current_function_name
);
5118 int num_gp_regs
= current_frame_info
.gp_reg_size
/ 4;
5119 int num_fp_regs
= current_frame_info
.fp_reg_size
/ 8;
5120 int num_regs
= num_gp_regs
+ num_fp_regs
;
5121 char *name
= current_function_name
;
5126 dslots_load_total
+= num_regs
;
5129 dslots_jump_total
++;
5133 dslots_load_filled
+= num_regs
;
5135 /* If the only register saved is the return register, we
5136 can't fill this register's delay slot. */
5138 if (load_only_r31
&& epilogue_delay
== 0)
5139 dslots_load_filled
--;
5141 if (tsize
> 0 || (!load_only_r31
&& epilogue_delay
!= 0))
5142 dslots_jump_filled
++;
5146 "%-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",
5148 (frame_pointer_needed
) ? 'y' : 'n',
5149 ((current_frame_info
.mask
& RA_MASK
) != 0) ? 'n' : 'y',
5150 (current_function_calls_alloca
) ? 'y' : 'n',
5151 (current_function_calls_setjmp
) ? 'y' : 'n',
5152 (long)current_frame_info
.total_size
,
5153 (long)current_function_outgoing_args_size
,
5154 num_gp_regs
, num_fp_regs
,
5155 dslots_load_total
, dslots_load_filled
,
5156 dslots_jump_total
, dslots_jump_filled
,
5157 num_refs
[0], num_refs
[1], num_refs
[2]);
5159 if (HALF_PIC_NUMBER_PTRS
> prev_half_pic_ptrs
)
5161 fprintf (stderr
, " half-pic=%3d", HALF_PIC_NUMBER_PTRS
- prev_half_pic_ptrs
);
5162 prev_half_pic_ptrs
= HALF_PIC_NUMBER_PTRS
;
5165 if (HALF_PIC_NUMBER_REFS
> prev_half_pic_refs
)
5167 fprintf (stderr
, " pic-ref=%3d", HALF_PIC_NUMBER_REFS
- prev_half_pic_refs
);
5168 prev_half_pic_refs
= HALF_PIC_NUMBER_REFS
;
5171 fputc ('\n', stderr
);
5174 /* Reset state info for each function. */
5175 inside_function
= FALSE
;
5176 ignore_line_number
= FALSE
;
5177 dslots_load_total
= 0;
5178 dslots_jump_total
= 0;
5179 dslots_load_filled
= 0;
5180 dslots_jump_filled
= 0;
5184 mips_load_reg
= (rtx
)0;
5185 mips_load_reg2
= (rtx
)0;
5186 current_frame_info
= zero_frame_info
;
5188 /* Restore the output file if optimizing the GP (optimizing the GP causes
5189 the text to be diverted to a tempfile, so that data decls come before
5190 references to the data). */
5193 asm_out_file
= asm_out_data_file
;
5197 /* Expand the epilogue into a bunch of separate insns. */
5200 mips_expand_epilogue ()
5202 long tsize
= current_frame_info
.total_size
;
5203 rtx tsize_rtx
= GEN_INT (tsize
);
5204 rtx tmp_rtx
= (rtx
)0;
5208 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
5209 emit_move_insn (tmp_rtx
, tsize_rtx
);
5210 tsize_rtx
= tmp_rtx
;
5215 if (frame_pointer_needed
)
5218 emit_insn (gen_movdi (stack_pointer_rtx
, frame_pointer_rtx
));
5220 emit_insn (gen_movsi (stack_pointer_rtx
, frame_pointer_rtx
));
5223 save_restore_insns (FALSE
, tmp_rtx
, tsize
, (FILE *)0);
5226 emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
5229 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
5233 emit_jump_insn (gen_return_internal (gen_rtx (REG
, Pmode
, GP_REG_FIRST
+31)));
5237 /* Define the number of delay slots needed for the function epilogue.
5239 On the mips, we need a slot if either no stack has been allocated,
5240 or the only register saved is the return register. */
5243 mips_epilogue_delay_slots ()
5245 if (!current_frame_info
.initialized
)
5246 (void) compute_frame_size (get_frame_size ());
5248 if (current_frame_info
.total_size
== 0)
5251 if (current_frame_info
.mask
== RA_MASK
&& current_frame_info
.fmask
== 0)
5258 /* Return true if this function is known to have a null epilogue.
5259 This allows the optimizer to omit jumps to jumps if no stack
5263 simple_epilogue_p ()
5265 if (!reload_completed
)
5268 if (current_frame_info
.initialized
)
5269 return current_frame_info
.total_size
== 0;
5271 return (compute_frame_size (get_frame_size ())) == 0;
5274 /* Choose the section to use for the constant rtx expression X that has
5277 mips_select_rtx_section (mode
, x
)
5278 enum machine_mode mode
;
5281 if (TARGET_EMBEDDED_DATA
)
5283 /* For embedded applications, always put constants in read-only data,
5284 in order to reduce RAM usage. */
5289 /* For hosted applications, always put constants in small data if
5290 possible, as this gives the best performance. */
5292 if (GET_MODE_SIZE (mode
) <= mips_section_threshold
5293 && mips_section_threshold
> 0)
5300 /* Choose the section to use for DECL. RELOC is true if its value contains
5301 any relocatable expression. */
5303 mips_select_section (decl
, reloc
)
5307 int size
= int_size_in_bytes (TREE_TYPE (decl
));
5309 if (TARGET_EMBEDDED_PIC
5310 && TREE_CODE (decl
) == STRING_CST
5311 && !flag_writable_strings
)
5313 /* For embedded position independent code, put constant strings
5314 in the text section, because the data section is limited to
5319 else if (TARGET_EMBEDDED_DATA
)
5321 /* For embedded applications, always put an object in read-only data
5322 if possible, in order to reduce RAM usage. */
5324 if (((TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
5325 && DECL_INITIAL (decl
)
5326 && (DECL_INITIAL (decl
) == error_mark_node
5327 || TREE_CONSTANT (DECL_INITIAL (decl
))))
5328 /* Deal with calls from output_constant_def_contents. */
5329 || (TREE_CODE (decl
) != VAR_DECL
5330 && (TREE_CODE (decl
) != STRING_CST
5331 || !flag_writable_strings
)))
5332 && ! (flag_pic
&& reloc
))
5334 else if (size
> 0 && size
<= mips_section_threshold
)
5341 /* For hosted applications, always put an object in small data if
5342 possible, as this gives the best performance. */
5344 if (size
> 0 && size
<= mips_section_threshold
)
5346 else if (((TREE_READONLY (decl
) && !TREE_SIDE_EFFECTS (decl
)
5347 && DECL_INITIAL (decl
)
5348 && (DECL_INITIAL (decl
) == error_mark_node
5349 || TREE_CONSTANT (DECL_INITIAL (decl
))))
5350 /* Deal with calls from output_constant_def_contents. */
5351 || (TREE_CODE (decl
) != VAR_DECL
5352 && (TREE_CODE (decl
) != STRING_CST
5353 || !flag_writable_strings
)))
5354 && ! (flag_pic
&& reloc
))