1 /* Subroutines for insn-output.c for MIPS
2 Contributed by A. Lichnewsky, lich@inria.inria.fr.
3 Changes by Michael Meissner, meissner@osf.org.
4 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "hard-reg-set.h"
27 #include "insn-config.h"
28 #include "conditions.h"
29 #include "insn-flags.h"
30 #include "insn-attr.h"
31 #include "insn-codes.h"
35 #undef MAX /* sys/param.h may also define these */
40 #include <sys/types.h>
53 #if defined(USG) || defined(NO_STAB_H)
54 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
56 #include <stab.h> /* On BSD, use the system's stab.h. */
60 #define STAB_CODE_TYPE enum __stab_debug_code
62 #define STAB_CODE_TYPE int
67 extern char *getenv ();
68 extern char *mktemp ();
70 extern rtx
adj_offsettable_operand ();
71 extern rtx
copy_to_reg ();
74 extern tree
lookup_name ();
75 extern void pfatal_with_name ();
76 extern void warning ();
78 extern tree current_function_decl
;
79 extern FILE *asm_out_file
;
81 /* Enumeration for all of the relational tests, so that we can build
82 arrays indexed by the test type, and not worry about the order
99 /* Global variables for machine-dependent things. */
101 /* Threshold for data being put into the small data/bss area, instead
102 of the normal data area (references to the small data/bss area take
103 1 instruction, and use the global pointer, references to the normal
104 data area takes 2 instructions). */
105 int mips_section_threshold
= -1;
107 /* Count the number of .file directives, so that .loc is up to date. */
108 int num_source_filenames
= 0;
110 /* Count the number of sdb related labels are generated (to find block
111 start and end boundaries). */
112 int sdb_label_count
= 0;
114 /* Next label # for each statment for Silicon Graphics IRIS systems. */
117 /* Non-zero if inside of a function, because the stupid MIPS asm can't
118 handle .files inside of functions. */
119 int inside_function
= 0;
121 /* Files to separate the text and the data output, so that all of the data
122 can be emitted before the text, which will mean that the assembler will
123 generate smaller code, based on the global pointer. */
124 FILE *asm_out_data_file
;
125 FILE *asm_out_text_file
;
127 /* Linked list of all externals that are to be emitted when optimizing
128 for the global pointer if they haven't been declared by the end of
129 the program with an appropriate .comm or initialization. */
132 struct extern_list
*next
; /* next external */
133 char *name
; /* name of the external */
134 int size
; /* size in bytes */
137 /* Name of the file containing the current function. */
138 char *current_function_file
= "";
140 /* Warning given that Mips ECOFF can't support changing files
141 within a function. */
142 int file_in_function_warning
= FALSE
;
144 /* Whether to suppress issuing .loc's because the user attempted
145 to change the filename within a function. */
146 int ignore_line_number
= FALSE
;
148 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
154 /* The next branch instruction is a branch likely, not branch normal. */
155 int mips_branch_likely
;
157 /* Count of delay slots and how many are filled. */
158 int dslots_load_total
;
159 int dslots_load_filled
;
160 int dslots_jump_total
;
161 int dslots_jump_filled
;
163 /* # of nops needed by previous insn */
164 int dslots_number_nops
;
166 /* Number of 1/2/3 word references to data items (ie, not jal's). */
169 /* registers to check for load delay */
170 rtx mips_load_reg
, mips_load_reg2
, mips_load_reg3
, mips_load_reg4
;
172 /* Cached operands, and operator to compare for use in set/branch on
176 /* what type of branch to use */
177 enum cmp_type branch_type
;
179 /* Number of previously seen half-pic pointers and references. */
180 static int prev_half_pic_ptrs
= 0;
181 static int prev_half_pic_refs
= 0;
183 /* which cpu are we scheduling for */
184 enum processor_type mips_cpu
;
186 /* which instruction set architecture to use. */
189 /* Strings to hold which cpu and instruction set architecture to use. */
190 char *mips_cpu_string
; /* for -mcpu=<xxx> */
191 char *mips_isa_string
; /* for -mips{1,2,3} */
193 /* Array to RTX class classification. At present, we care about
194 whether the operator is an add-type operator, or a divide/modulus,
195 and if divide/modulus, whether it is unsigned. This is for the
197 char mips_rtx_classify
[NUM_RTX_CODE
];
199 /* Array giving truth value on whether or not a given hard register
200 can support a given mode. */
201 char mips_hard_regno_mode_ok
[(int)MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
203 /* Current frame information calculated by compute_frame_size. */
204 struct mips_frame_info current_frame_info
;
206 /* Zero structure to initialize current_frame_info. */
207 struct mips_frame_info zero_frame_info
;
209 /* Temporary filename used to buffer .text until end of program
211 static char *temp_filename
;
213 /* List of all MIPS punctuation characters used by print_operand. */
214 char mips_print_operand_punct
[256];
216 /* Map GCC register number to debugger register number. */
217 int mips_dbx_regno
[FIRST_PSEUDO_REGISTER
];
219 /* Buffer to use to enclose a load/store operation with %{ %} to
220 turn on .set volatile. */
221 static char volatile_buffer
[60];
223 /* Hardware names for the registers. If -mrnames is used, this
224 will be overwritten with mips_sw_reg_names. */
226 char mips_reg_names
[][8] =
228 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
229 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
230 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
231 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
232 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
233 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
234 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
235 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
239 /* Mips software names for the registers, used to overwrite the
240 mips_reg_names array. */
242 char mips_sw_reg_names
[][8] =
244 "$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
245 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
246 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
247 "t8", "t9", "k0", "k1", "gp", "sp", "$fp", "ra",
248 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
249 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
250 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
251 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
255 /* Map hard register number to register class */
256 enum reg_class mips_regno_to_class
[] =
258 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
259 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
260 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
261 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
262 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
263 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
264 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
265 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
266 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
267 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
268 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
269 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
270 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
271 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
272 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
273 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
274 HI_REG
, LO_REG
, ST_REGS
277 /* Map register constraint character to register class. */
278 enum reg_class mips_char_to_class
[256] =
280 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
281 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
282 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
283 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
284 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
285 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
286 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
287 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
288 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
289 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
290 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
291 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
292 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
293 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
294 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
295 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
296 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
297 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
298 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
299 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
300 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
301 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
302 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
303 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
304 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
305 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
306 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
307 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
308 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
309 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
310 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
311 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
312 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
313 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
314 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
315 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
316 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
317 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
318 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
319 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
320 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
321 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
322 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
323 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
324 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
325 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
326 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
327 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
328 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
329 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
330 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
331 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
332 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
333 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
334 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
335 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
336 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
337 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
338 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
339 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
340 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
341 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
342 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
343 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
347 /* Return truth value of whether OP can be used as an operands
348 where a register or 16 bit unsigned integer is needed. */
351 uns_arith_operand (op
, mode
)
353 enum machine_mode mode
;
355 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT_UNSIGNED (op
))
358 return register_operand (op
, mode
);
361 /* Return truth value of whether OP can be used as an operands
362 where a 16 bit integer is needed */
365 arith_operand (op
, mode
)
367 enum machine_mode mode
;
369 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
))
372 return register_operand (op
, mode
);
375 /* Return truth value of whether OP can be used as an operand in a two
376 address arithmetic insn (such as set 123456,%o4) of mode MODE. */
379 arith32_operand (op
, mode
)
381 enum machine_mode mode
;
383 if (GET_CODE (op
) == CONST_INT
)
386 return register_operand (op
, mode
);
389 /* Return truth value of whether OP is a integer which fits in 16 bits */
394 enum machine_mode mode
;
396 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
399 /* Return truth value of whether OP is an integer which is too big to
400 be loaded with one instruction. */
405 enum machine_mode mode
;
409 if (GET_CODE (op
) != CONST_INT
)
413 if ((value
& ~0x0000ffff) == 0) /* ior reg,$r0,value */
416 if (((unsigned long)(value
+ 32768)) <= 32767) /* subu reg,$r0,value */
419 if ((value
& 0xffff0000) == value
) /* lui reg,value>>16 */
425 /* Return truth value of whether OP is a register or the constant 0. */
428 reg_or_0_operand (op
, mode
)
430 enum machine_mode mode
;
432 switch (GET_CODE (op
))
438 return (INTVAL (op
) == 0);
441 if (CONST_DOUBLE_HIGH (op
) != 0 || CONST_DOUBLE_LOW (op
) != 0)
448 return register_operand (op
, mode
);
454 /* Return truth value of whether OP is one of the special multiply/divide
455 registers (hi, lo). */
458 md_register_operand (op
, mode
)
460 enum machine_mode mode
;
462 return (GET_MODE_CLASS (mode
) == MODE_INT
463 && GET_CODE (op
) == REG
464 && MD_REG_P (REGNO (op
)));
467 /* Return truth value of whether OP is the FP status register. */
470 fpsw_register_operand (op
, mode
)
472 enum machine_mode mode
;
474 return (GET_CODE (op
) == REG
&& ST_REG_P (REGNO (op
)));
477 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
480 mips_const_double_ok (op
, mode
)
482 enum machine_mode mode
;
484 if (GET_CODE (op
) != CONST_DOUBLE
)
490 if (mode
!= SFmode
&& mode
!= DFmode
)
493 if (CONST_DOUBLE_HIGH (op
) == 0 && CONST_DOUBLE_LOW (op
) == 0)
496 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
497 if (TARGET_MIPS_AS
) /* gas doesn't like li.d/li.s yet */
499 union { double d
; int i
[2]; } u
;
502 u
.i
[0] = CONST_DOUBLE_LOW (op
);
503 u
.i
[1] = CONST_DOUBLE_HIGH (op
);
507 return FALSE
; /* NAN */
512 /* Rather than trying to get the accuracy down to the last bit,
513 just use approximate ranges. */
515 if (mode
== DFmode
&& d
> 1.0e-300 && d
< 1.0e300
)
518 if (mode
== SFmode
&& d
> 1.0e-38 && d
< 1.0e+38)
526 /* Return truth value if a memory operand fits in a single instruction
527 (ie, register + small offset). */
530 simple_memory_operand (op
, mode
)
532 enum machine_mode mode
;
534 rtx addr
, plus0
, plus1
;
536 /* Eliminate non-memory operations */
537 if (GET_CODE (op
) != MEM
)
540 /* dword operations really put out 2 instructions, so eliminate them. */
541 if (GET_MODE_SIZE (GET_MODE (op
)) > (HAVE_64BIT_P () ? 8 : 4))
544 /* Decode the address now. */
546 switch (GET_CODE (addr
))
555 return SMALL_INT (op
);
558 plus0
= XEXP (addr
, 0);
559 plus1
= XEXP (addr
, 1);
560 if (GET_CODE (plus0
) == REG
561 && GET_CODE (plus1
) == CONST_INT
562 && SMALL_INT (plus1
))
565 else if (GET_CODE (plus1
) == REG
566 && GET_CODE (plus0
) == CONST_INT
567 && SMALL_INT (plus0
))
574 /* We used to allow small symbol refs here (ie, stuff in .sdata
575 or .sbss), but this causes some bugs in G++. Also, it won't
576 interfere if the MIPS linker rewrites the store instruction
577 because the function is PIC. */
579 case LABEL_REF
: /* never gp relative */
583 /* If -G 0, we can never have a GP relative memory operation.
584 Also, save some time if not optimizing. */
585 if (mips_section_threshold
== 0 || !optimize
|| !TARGET_GP_OPT
)
589 rtx offset
= const0_rtx
;
590 addr
= eliminate_constant_term (addr
, &offset
);
591 if (GET_CODE (op
) != SYMBOL_REF
)
594 /* let's be paranoid.... */
595 if (INTVAL (offset
) < 0 || INTVAL (offset
) > 0xffff)
601 return SYMBOL_REF_FLAG (addr
);
608 /* Return true if the code of this rtx pattern is EQ or NE. */
611 equality_op (op
, mode
)
613 enum machine_mode mode
;
615 if (mode
!= GET_MODE (op
))
618 return (classify_op (op
, mode
) & CLASS_EQUALITY_OP
) != 0;
621 /* Return true if the code is a relational operations (EQ, LE, etc.) */
626 enum machine_mode mode
;
628 if (mode
!= GET_MODE (op
))
631 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
635 /* Genrecog does not take the type of match_operator into consideration,
636 and would complain about two patterns being the same if the same
637 function is used, so make it believe they are different. */
642 enum machine_mode mode
;
644 if (mode
!= GET_MODE (op
))
647 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
650 /* Return true if the code is an unsigned relational operations (LEU, etc.) */
655 enum machine_mode mode
;
657 if (mode
!= GET_MODE (op
))
660 return (classify_op (op
, mode
) & CLASS_UNS_CMP_OP
) == CLASS_UNS_CMP_OP
;
663 /* Return true if the code is a relational operation FP can use. */
668 enum machine_mode mode
;
670 if (mode
!= GET_MODE (op
))
673 return (classify_op (op
, mode
) & CLASS_FCMP_OP
) != 0;
677 /* Return true if the operand is either the PC or a label_ref. */
680 pc_or_label_operand (op
, mode
)
682 enum machine_mode mode
;
687 if (GET_CODE (op
) == LABEL_REF
)
693 /* Test for a valid operand for a call instruction.
694 Don't allow the arg pointer register or virtual regs
695 since they may change into reg + const, which the patterns
699 call_insn_operand (op
, mode
)
701 enum machine_mode mode
;
703 if (GET_CODE (op
) == MEM
704 && (CONSTANT_ADDRESS_P (XEXP (op
, 0))
705 || (GET_CODE (XEXP (op
, 0)) == REG
706 && XEXP (op
, 0) != arg_pointer_rtx
707 && !(REGNO (XEXP (op
, 0)) >= FIRST_PSEUDO_REGISTER
708 && REGNO (XEXP (op
, 0)) <= LAST_VIRTUAL_REGISTER
))))
713 /* Return an operand string if the given instruction's delay slot or
714 wrap it in a .set noreorder section. This is for filling delay
715 slots on load type instructions under GAS, which does no reordering
716 on its own. For the MIPS assembler, all we do is update the filled
717 delay slot statistics.
719 We assume that operands[0] is the target register that is set.
721 In order to check the next insn, most of this functionality is moved
722 to FINAL_PRESCAN_INSN, and we just set the global variables that
726 mips_fill_delay_slot (ret
, type
, operands
, cur_insn
)
727 char *ret
; /* normal string to return */
728 enum delay_type type
; /* type of delay */
729 rtx operands
[]; /* operands to use */
730 rtx cur_insn
; /* current insn */
732 register rtx set_reg
;
733 register enum machine_mode mode
;
734 register rtx next_insn
= (cur_insn
) ? NEXT_INSN (cur_insn
) : (rtx
)0;
735 register int num_nops
;
737 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
740 else if (type
== DELAY_HILO
)
746 /* Make sure that we don't put nop's after labels. */
747 next_insn
= NEXT_INSN (cur_insn
);
748 while (next_insn
!= (rtx
)0 && GET_CODE (next_insn
) == NOTE
)
749 next_insn
= NEXT_INSN (next_insn
);
751 dslots_load_total
+= num_nops
;
752 if (TARGET_DEBUG_F_MODE
754 || type
== DELAY_NONE
755 || operands
== (rtx
*)0
756 || cur_insn
== (rtx
)0
757 || next_insn
== (rtx
)0
758 || GET_CODE (next_insn
) == CODE_LABEL
759 || (set_reg
= operands
[0]) == (rtx
)0)
761 dslots_number_nops
= 0;
762 mips_load_reg
= (rtx
)0;
763 mips_load_reg2
= (rtx
)0;
764 mips_load_reg3
= (rtx
)0;
765 mips_load_reg4
= (rtx
)0;
769 set_reg
= operands
[0];
770 if (set_reg
== (rtx
)0)
773 while (GET_CODE (set_reg
) == SUBREG
)
774 set_reg
= SUBREG_REG (set_reg
);
776 mode
= GET_MODE (set_reg
);
777 dslots_number_nops
= num_nops
;
778 mips_load_reg
= set_reg
;
779 mips_load_reg2
= (mode
== DImode
|| mode
== DFmode
)
780 ? gen_rtx (REG
, SImode
, REGNO (set_reg
) + 1)
783 if (type
== DELAY_HILO
)
785 mips_load_reg3
= gen_rtx (REG
, SImode
, MD_REG_FIRST
);
786 mips_load_reg4
= gen_rtx (REG
, SImode
, MD_REG_FIRST
+1);
794 if (TARGET_GAS
&& set_noreorder
++ == 0)
795 fputs ("\t.set\tnoreorder\n", asm_out_file
);
801 /* Determine whether a memory reference takes one (based off of the GP pointer),
802 two (normal), or three (label + reg) instructions, and bump the appropriate
803 counter for -mstats. */
806 mips_count_memory_refs (op
, num
)
812 rtx addr
, plus0
, plus1
;
813 enum rtx_code code0
, code1
;
816 if (TARGET_DEBUG_B_MODE
)
818 fprintf (stderr
, "\n========== mips_count_memory_refs:\n");
822 /* Skip MEM if passed, otherwise handle movsi of address. */
823 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
825 /* Loop, going through the address RTL */
829 switch (GET_CODE (addr
))
839 plus0
= XEXP (addr
, 0);
840 plus1
= XEXP (addr
, 1);
841 code0
= GET_CODE (plus0
);
842 code1
= GET_CODE (plus1
);
852 if (code0
== CONST_INT
)
867 if (code1
== CONST_INT
)
874 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
881 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
891 n_words
= 2; /* always 2 words */
895 addr
= XEXP (addr
, 0);
900 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
909 n_words
+= additional
;
913 num_refs
[n_words
-1] += num
;
917 /* Return the appropriate instructions to move one operand to another. */
920 mips_move_1word (operands
, insn
, unsignedp
)
926 rtx op0
= operands
[0];
927 rtx op1
= operands
[1];
928 enum rtx_code code0
= GET_CODE (op0
);
929 enum rtx_code code1
= GET_CODE (op1
);
930 enum machine_mode mode
= GET_MODE (op0
);
931 int subreg_word0
= 0;
932 int subreg_word1
= 0;
933 enum delay_type delay
= DELAY_NONE
;
935 while (code0
== SUBREG
)
937 subreg_word0
+= SUBREG_WORD (op0
);
938 op0
= SUBREG_REG (op0
);
939 code0
= GET_CODE (op0
);
942 while (code1
== SUBREG
)
944 subreg_word1
+= SUBREG_WORD (op1
);
945 op1
= SUBREG_REG (op1
);
946 code1
= GET_CODE (op1
);
951 int regno0
= REGNO (op0
) + subreg_word0
;
955 int regno1
= REGNO (op1
) + subreg_word1
;
957 /* Just in case, don't do anything for assigning a register
958 to itself, unless we are filling a delay slot. */
959 if (regno0
== regno1
&& set_nomacro
== 0)
962 else if (GP_REG_P (regno0
))
964 if (GP_REG_P (regno1
))
967 else if (MD_REG_P (regno1
))
976 if (FP_REG_P (regno1
))
979 else if (regno1
== FPSW_REGNUM
)
980 ret
= "cfc1\t%0,$31";
984 else if (FP_REG_P (regno0
))
986 if (GP_REG_P (regno1
))
992 if (FP_REG_P (regno1
))
993 ret
= "mov.s\t%0,%1";
996 else if (MD_REG_P (regno0
))
998 if (GP_REG_P (regno1
))
1005 else if (regno0
== FPSW_REGNUM
)
1007 if (GP_REG_P (regno1
))
1010 ret
= "ctc1\t%0,$31";
1015 else if (code1
== MEM
)
1020 mips_count_memory_refs (op1
, 1);
1022 if (GP_REG_P (regno0
))
1024 /* For loads, use the mode of the memory item, instead of the
1025 target, so zero/sign extend can use this code as well. */
1026 switch (GET_MODE (op1
))
1029 case SFmode
: ret
= "lw\t%0,%1"; break;
1030 case SImode
: ret
= "lw\t%0,%1"; break;
1031 case HImode
: ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1"; break;
1032 case QImode
: ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1"; break;
1036 else if (FP_REG_P (regno0
) && (mode
== SImode
|| mode
== SFmode
))
1039 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1041 int i
= strlen (ret
);
1042 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1045 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1046 ret
= volatile_buffer
;
1050 else if (code1
== CONST_INT
)
1052 if (INTVAL (op1
) == 0)
1054 if (GP_REG_P (regno0
))
1055 ret
= "move\t%0,%z1";
1057 else if (FP_REG_P (regno0
))
1060 ret
= "mtc1\t%z1,%0";
1064 else if (GP_REG_P (regno0
))
1065 ret
= (INTVAL (op1
) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1";
1068 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
1070 if (CONST_DOUBLE_HIGH (op1
) == 0 && CONST_DOUBLE_LOW (op1
) == 0)
1072 if (GP_REG_P (regno0
))
1073 ret
= "move\t%0,%.";
1075 else if (FP_REG_P (regno0
))
1078 ret
= "mtc1\t%.,%0";
1085 ret
= "li.s\t%0,%1";
1089 else if (code1
== LABEL_REF
)
1092 mips_count_memory_refs (op1
, 1);
1097 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
1099 if (HALF_PIC_P () && CONSTANT_P (op1
) && HALF_PIC_ADDRESS_P (op1
))
1101 rtx offset
= const0_rtx
;
1103 if (GET_CODE (op1
) == CONST
)
1104 op1
= eliminate_constant_term (XEXP (op1
, 0), &offset
);
1106 if (GET_CODE (op1
) == SYMBOL_REF
)
1108 operands
[2] = HALF_PIC_PTR (op1
);
1111 mips_count_memory_refs (operands
[2], 1);
1113 if (INTVAL (offset
) == 0)
1120 dslots_load_total
++;
1121 operands
[3] = offset
;
1122 ret
= (SMALL_INT (offset
))
1123 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"
1124 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1131 mips_count_memory_refs (op1
, 1);
1137 else if (code1
== PLUS
)
1139 rtx add_op0
= XEXP (op1
, 0);
1140 rtx add_op1
= XEXP (op1
, 1);
1142 if (GET_CODE (XEXP (op1
, 1)) == REG
&& GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
1144 add_op0
= XEXP (op1
, 1); /* reverse operands */
1145 add_op1
= XEXP (op1
, 0);
1148 operands
[2] = add_op0
;
1149 operands
[3] = add_op1
;
1150 ret
= "add%:\t%0,%2,%3";
1154 else if (code0
== MEM
)
1157 mips_count_memory_refs (op0
, 1);
1161 int regno1
= REGNO (op1
) + subreg_word1
;
1163 if (GP_REG_P (regno1
))
1168 case SFmode
: ret
= "sw\t%1,%0"; break;
1169 case SImode
: ret
= "sw\t%1,%0"; break;
1170 case HImode
: ret
= "sh\t%1,%0"; break;
1171 case QImode
: ret
= "sb\t%1,%0"; break;
1175 else if (FP_REG_P (regno1
) && (mode
== SImode
|| mode
== SFmode
))
1179 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1184 case SFmode
: ret
= "sw\t%z1,%0"; break;
1185 case SImode
: ret
= "sw\t%z1,%0"; break;
1186 case HImode
: ret
= "sh\t%z1,%0"; break;
1187 case QImode
: ret
= "sb\t%z1,%0"; break;
1191 else if (code1
== CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op1
) == 0 && CONST_DOUBLE_LOW (op1
) == 0)
1196 case SFmode
: ret
= "sw\t%.,%0"; break;
1197 case SImode
: ret
= "sw\t%.,%0"; break;
1198 case HImode
: ret
= "sh\t%.,%0"; break;
1199 case QImode
: ret
= "sb\t%.,%0"; break;
1203 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1205 int i
= strlen (ret
);
1206 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1209 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1210 ret
= volatile_buffer
;
1214 if (ret
== (char *)0)
1216 abort_with_insn (insn
, "Bad move");
1220 if (delay
!= DELAY_NONE
)
1221 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1227 /* Return the appropriate instructions to move 2 words */
1230 mips_move_2words (operands
, insn
)
1235 rtx op0
= operands
[0];
1236 rtx op1
= operands
[1];
1237 enum rtx_code code0
= GET_CODE (operands
[0]);
1238 enum rtx_code code1
= GET_CODE (operands
[1]);
1239 int subreg_word0
= 0;
1240 int subreg_word1
= 0;
1241 enum delay_type delay
= DELAY_NONE
;
1243 while (code0
== SUBREG
)
1245 subreg_word0
+= SUBREG_WORD (op0
);
1246 op0
= SUBREG_REG (op0
);
1247 code0
= GET_CODE (op0
);
1250 while (code1
== SUBREG
)
1252 subreg_word1
+= SUBREG_WORD (op1
);
1253 op1
= SUBREG_REG (op1
);
1254 code1
= GET_CODE (op1
);
1259 int regno0
= REGNO (op0
) + subreg_word0
;
1263 int regno1
= REGNO (op1
) + subreg_word1
;
1265 /* Just in case, don't do anything for assigning a register
1266 to itself, unless we are filling a delay slot. */
1267 if (regno0
== regno1
&& set_nomacro
== 0)
1270 else if (FP_REG_P (regno0
))
1272 if (FP_REG_P (regno1
))
1273 ret
= "mov.d\t%0,%1";
1278 ret
= (TARGET_FLOAT64
)
1280 : "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";
1284 else if (FP_REG_P (regno1
))
1287 ret
= (TARGET_FLOAT64
)
1289 : "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";
1292 else if (MD_REG_P (regno0
) && GP_REG_P (regno1
))
1295 ret
= "mthi\t%M1\n\tmtlo\t%L1";
1298 else if (GP_REG_P (regno0
) && MD_REG_P (regno1
))
1301 ret
= "mfhi\t%M0\n\tmflo\t%L0";
1304 else if (regno0
!= (regno1
+1))
1305 ret
= "move\t%0,%1\n\tmove\t%D0,%D1";
1308 ret
= "move\t%D0,%D1\n\tmove\t%0,%1";
1311 else if (code1
== CONST_DOUBLE
)
1313 if (CONST_DOUBLE_HIGH (op1
) != 0 || CONST_DOUBLE_LOW (op1
) != 0)
1315 if (GET_MODE (op1
) == DFmode
)
1318 ret
= "li.d\t%0,%1";
1323 operands
[2] = GEN_INT (CONST_DOUBLE_LOW (op1
));
1324 operands
[3] = GEN_INT (CONST_DOUBLE_HIGH (op1
));
1325 ret
= "li\t%M0,%3\n\tli\t%L0,%2";
1331 if (GP_REG_P (regno0
))
1332 ret
= "move\t%0,%.\n\tmove\t%D0,%.";
1334 else if (FP_REG_P (regno0
))
1337 ret
= (TARGET_FLOAT64
)
1339 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1344 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1346 if (GP_REG_P (regno0
))
1347 ret
= "move\t%0,%.\n\tmove\t%D0,%.";
1349 else if (FP_REG_P (regno0
))
1352 ret
= (TARGET_FLOAT64
)
1354 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1358 else if (code1
== CONST_INT
&& GET_MODE (op0
) == DImode
&& GP_REG_P (regno0
))
1360 operands
[2] = GEN_INT (INTVAL (operands
[1]) >= 0 ? 0 : -1);
1361 ret
= "li\t%M0,%2\n\tli\t%L0,%1";
1364 else if (code1
== MEM
)
1369 mips_count_memory_refs (op1
, 2);
1371 if (FP_REG_P (regno0
))
1374 else if (offsettable_address_p (1, DFmode
, XEXP (op1
, 0)))
1376 operands
[2] = adj_offsettable_operand (op1
, 4);
1377 if (reg_mentioned_p (op0
, op1
))
1378 ret
= "lw\t%D0,%2\n\tlw\t%0,%1";
1380 ret
= "lw\t%0,%1\n\tlw\t%D0,%2";
1383 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1385 int i
= strlen (ret
);
1386 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1389 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1390 ret
= volatile_buffer
;
1395 else if (code0
== MEM
)
1399 int regno1
= REGNO (op1
) + subreg_word1
;
1401 if (FP_REG_P (regno1
))
1404 else if (offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1406 operands
[2] = adj_offsettable_operand (op0
, 4);
1407 ret
= "sw\t%1,%0\n\tsw\t%D1,%2";
1411 else if (code1
== CONST_DOUBLE
1412 && CONST_DOUBLE_HIGH (op1
) == 0
1413 && CONST_DOUBLE_LOW (op1
) == 0
1414 && offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1420 operands
[2] = adj_offsettable_operand (op0
, 4);
1421 ret
= "sw\t%.,%0\n\tsw\t%.,%2";
1426 mips_count_memory_refs (op0
, 2);
1428 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1430 int i
= strlen (ret
);
1431 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1434 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1435 ret
= volatile_buffer
;
1439 if (ret
== (char *)0)
1441 abort_with_insn (insn
, "Bad move");
1445 if (delay
!= DELAY_NONE
)
1446 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1452 /* Provide the costs of an addressing mode that contains ADDR.
1453 If ADDR is not a valid address, its cost is irrelevant. */
1456 mips_address_cost (addr
)
1459 switch (GET_CODE (addr
))
1473 rtx offset
= const0_rtx
;
1474 addr
= eliminate_constant_term (addr
, &offset
);
1475 if (GET_CODE (addr
) == LABEL_REF
)
1478 if (GET_CODE (addr
) != SYMBOL_REF
)
1481 if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
1487 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
1491 register rtx plus0
= XEXP (addr
, 0);
1492 register rtx plus1
= XEXP (addr
, 1);
1494 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1496 plus0
= XEXP (addr
, 1);
1497 plus1
= XEXP (addr
, 0);
1500 if (GET_CODE (plus0
) != REG
)
1503 switch (GET_CODE (plus1
))
1510 int value
= INTVAL (plus1
);
1511 return (value
< -32768 || value
> 32767) ? 2 : 1;
1519 return mips_address_cost (plus1
) + 1;
1528 /* Make normal rtx_code into something we can index from an array */
1530 static enum internal_test
1531 map_test_to_internal_test (test_code
)
1532 enum rtx_code test_code
;
1534 enum internal_test test
= ITEST_MAX
;
1539 case EQ
: test
= ITEST_EQ
; break;
1540 case NE
: test
= ITEST_NE
; break;
1541 case GT
: test
= ITEST_GT
; break;
1542 case GE
: test
= ITEST_GE
; break;
1543 case LT
: test
= ITEST_LT
; break;
1544 case LE
: test
= ITEST_LE
; break;
1545 case GTU
: test
= ITEST_GTU
; break;
1546 case GEU
: test
= ITEST_GEU
; break;
1547 case LTU
: test
= ITEST_LTU
; break;
1548 case LEU
: test
= ITEST_LEU
; break;
1555 /* Generate the code to compare two integer values. The return value is:
1556 (reg:SI xx) The pseudo register the comparison is in
1557 (rtx)0 No register, generate a simple branch. */
1560 gen_int_relational (test_code
, result
, cmp0
, cmp1
, p_invert
)
1561 enum rtx_code test_code
; /* relational test (EQ, etc) */
1562 rtx result
; /* result to store comp. or 0 if branch */
1563 rtx cmp0
; /* first operand to compare */
1564 rtx cmp1
; /* second operand to compare */
1565 int *p_invert
; /* NULL or ptr to hold whether branch needs */
1566 /* to reverse its test */
1569 enum rtx_code test_code
; /* code to use in instruction (LT vs. LTU) */
1570 int const_low
; /* low bound of constant we can accept */
1571 int const_high
; /* high bound of constant we can accept */
1572 int const_add
; /* constant to add (convert LE -> LT) */
1573 int reverse_regs
; /* reverse registers in test */
1574 int invert_const
; /* != 0 if invert value if cmp1 is constant */
1575 int invert_reg
; /* != 0 if invert value if cmp1 is register */
1576 int unsignedp
; /* != 0 for unsigned comparisons. */
1579 static struct cmp_info info
[ (int)ITEST_MAX
] = {
1581 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1582 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1583 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1584 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1585 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1586 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1587 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1588 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1589 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1590 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1593 enum internal_test test
;
1594 struct cmp_info
*p_info
;
1601 test
= map_test_to_internal_test (test_code
);
1602 if (test
== ITEST_MAX
)
1605 p_info
= &info
[ (int)test
];
1606 eqne_p
= (p_info
->test_code
== XOR
);
1608 /* Eliminate simple branches */
1609 branch_p
= (result
== (rtx
)0);
1612 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
1614 /* Comparisons against zero are simple branches */
1615 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1618 /* Test for beq/bne. */
1623 /* allocate a pseudo to calculate the value in. */
1624 result
= gen_reg_rtx (SImode
);
1627 /* Make sure we can handle any constants given to us. */
1628 if (GET_CODE (cmp0
) == CONST_INT
)
1629 cmp0
= force_reg (SImode
, cmp0
);
1631 if (GET_CODE (cmp1
) == CONST_INT
)
1633 HOST_WIDE_INT value
= INTVAL (cmp1
);
1634 if (value
< p_info
->const_low
|| value
> p_info
->const_high
)
1635 cmp1
= force_reg (SImode
, cmp1
);
1638 /* See if we need to invert the result. */
1639 invert
= (GET_CODE (cmp1
) == CONST_INT
)
1640 ? p_info
->invert_const
1641 : p_info
->invert_reg
;
1643 if (p_invert
!= (int *)0)
1649 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1650 Comparison between two registers, may involve switching operands. */
1651 if (GET_CODE (cmp1
) == CONST_INT
)
1653 if (p_info
->const_add
!= 0)
1655 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
1656 /* If modification of cmp1 caused overflow,
1657 we would get the wrong answer if we follow the usual path;
1658 thus, x > 0xffffffffu would turn into x > 0u. */
1659 if ((p_info
->unsignedp
1660 ? (unsigned HOST_WIDE_INT
) new > INTVAL (cmp1
)
1661 : new > INTVAL (cmp1
))
1662 != (p_info
->const_add
> 0))
1664 /* This test is always true, but if INVERT is true then
1665 the result of the test needs to be inverted so 0 should
1666 be returned instead. */
1667 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1671 cmp1
= GEN_INT (new);
1674 else if (p_info
->reverse_regs
)
1681 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1685 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (SImode
) : result
;
1686 emit_move_insn (reg
, gen_rtx (p_info
->test_code
, SImode
, cmp0
, cmp1
));
1689 if (test
== ITEST_NE
)
1691 emit_move_insn (result
, gen_rtx (GTU
, SImode
, reg
, const0_rtx
));
1695 else if (test
== ITEST_EQ
)
1697 reg2
= (invert
) ? gen_reg_rtx (SImode
) : result
;
1698 emit_move_insn (reg2
, gen_rtx (LTU
, SImode
, reg
, const1_rtx
));
1703 emit_move_insn (result
, gen_rtx (XOR
, SImode
, reg
, const1_rtx
));
1709 /* Emit the common code for doing conditional branches.
1710 operand[0] is the label to jump to.
1711 The comparison operands are saved away by cmp{si,sf,df}. */
1714 gen_conditional_branch (operands
, test_code
)
1716 enum rtx_code test_code
;
1718 static enum machine_mode mode_map
[(int)CMP_MAX
][(int)ITEST_MAX
] = {
1733 CC_REV_FPmode
, /* ne */
1745 CC_REV_FPmode
, /* ne */
1757 enum machine_mode mode
;
1758 enum cmp_type type
= branch_type
;
1759 rtx cmp0
= branch_cmp
[0];
1760 rtx cmp1
= branch_cmp
[1];
1761 rtx label1
= gen_rtx (LABEL_REF
, VOIDmode
, operands
[0]);
1762 rtx label2
= pc_rtx
;
1765 enum internal_test test
= map_test_to_internal_test (test_code
);
1767 if (test
== ITEST_MAX
)
1773 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
1774 mode
= mode_map
[(int)type
][(int)test
];
1775 if (mode
== VOIDmode
)
1778 switch (branch_type
)
1784 reg
= gen_int_relational (test_code
, (rtx
)0, cmp0
, cmp1
, &invert
);
1792 /* Make sure not non-zero constant if ==/!= */
1793 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1794 cmp1
= force_reg (SImode
, cmp1
);
1801 rtx reg
= gen_rtx (REG
, mode
, FPSW_REGNUM
);
1802 emit_insn (gen_rtx (SET
, VOIDmode
, reg
, gen_rtx (test_code
, mode
, cmp0
, cmp1
)));
1810 /* Generate the jump */
1817 emit_jump_insn (gen_rtx (SET
, VOIDmode
,
1819 gen_rtx (IF_THEN_ELSE
, VOIDmode
,
1820 gen_rtx (test_code
, mode
, cmp0
, cmp1
),
1827 abort_with_insn (gen_rtx (test_code
, mode
, cmp0
, cmp1
), "bad test");
1831 #define UNITS_PER_SHORT (SHORT_TYPE_SIZE / BITS_PER_UNIT)
1833 /* Internal code to generate the load and store of one word/short/byte.
1834 The load is emitted directly, and the store insn is returned. */
1838 block_move_load_store (dest_reg
, src_reg
, p_bytes
, p_offset
, align
, orig_src
)
1839 rtx src_reg
; /* register holding source memory address */
1840 rtx dest_reg
; /* register holding dest. memory address */
1841 int *p_bytes
; /* pointer to # bytes remaining */
1842 int *p_offset
; /* pointer to current offset */
1843 int align
; /* alignment */
1844 rtx orig_src
; /* original source for making a reg note */
1846 int bytes
; /* # bytes remaining */
1847 int offset
; /* offset to use */
1848 int size
; /* size in bytes of load/store */
1849 enum machine_mode mode
; /* mode to use for load/store */
1850 rtx reg
; /* temporary register */
1851 rtx src_addr
; /* source address */
1852 rtx dest_addr
; /* destination address */
1853 rtx insn
; /* insn of the load */
1854 rtx orig_src_addr
; /* original source address */
1855 rtx (*load_func
)(); /* function to generate load insn */
1856 rtx (*store_func
)(); /* function to generate destination insn */
1859 if (bytes
<= 0 || align
<= 0)
1862 if (bytes
>= UNITS_PER_WORD
&& align
>= UNITS_PER_WORD
)
1865 size
= UNITS_PER_WORD
;
1866 load_func
= gen_movsi
;
1867 store_func
= gen_movsi
;
1871 /* Don't generate unaligned moves here, rather defer those to the
1872 general movestrsi_internal pattern. */
1873 else if (bytes
>= UNITS_PER_WORD
)
1876 size
= UNITS_PER_WORD
;
1877 load_func
= gen_movsi_ulw
;
1878 store_func
= gen_movsi_usw
;
1882 else if (bytes
>= UNITS_PER_SHORT
&& align
>= UNITS_PER_SHORT
)
1885 size
= UNITS_PER_SHORT
;
1886 load_func
= gen_movhi
;
1887 store_func
= gen_movhi
;
1894 load_func
= gen_movqi
;
1895 store_func
= gen_movqi
;
1899 *p_offset
= offset
+ size
;
1900 *p_bytes
= bytes
- size
;
1905 dest_addr
= dest_reg
;
1909 src_addr
= gen_rtx (PLUS
, Pmode
, src_reg
, GEN_INT (offset
));
1910 dest_addr
= gen_rtx (PLUS
, Pmode
, dest_reg
, GEN_INT (offset
));
1913 reg
= gen_reg_rtx (mode
);
1914 insn
= emit_insn ((*load_func
) (reg
, gen_rtx (MEM
, mode
, src_addr
)));
1915 orig_src_addr
= XEXP (orig_src
, 0);
1916 if (CONSTANT_P (orig_src_addr
))
1917 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUIV
,
1918 plus_constant (orig_src_addr
, offset
),
1921 return (*store_func
) (gen_rtx (MEM
, mode
, dest_addr
), reg
);
1926 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows:
1938 This way, no NOP's are needed, except at the end, and only
1939 two temp registers are needed. Two delay slots are used
1940 in deference to the R4000. */
1944 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
)
1945 rtx dest_reg
; /* register holding destination address */
1946 rtx src_reg
; /* register holding source address */
1947 int bytes
; /* # bytes to move */
1948 int align
; /* max alignment to assume */
1949 rtx orig_src
; /* original source for making a reg note */
1952 rtx prev2_store
= (rtx
)0;
1953 rtx prev_store
= (rtx
)0;
1954 rtx cur_store
= (rtx
)0;
1958 /* Is there a store to do? */
1960 emit_insn (prev2_store
);
1962 prev2_store
= prev_store
;
1963 prev_store
= cur_store
;
1964 cur_store
= block_move_load_store (dest_reg
, src_reg
,
1969 /* Finish up last three stores. */
1971 emit_insn (prev2_store
);
1974 emit_insn (prev_store
);
1977 emit_insn (cur_store
);
1982 /* Write a loop to move a constant number of bytes. Generate load/stores as follows:
1988 temp<last> = src[MAX_MOVE_REGS-1];
1992 dest[MAX_MOVE_REGS-1] = temp<last>;
1993 src += MAX_MOVE_REGS;
1994 dest += MAX_MOVE_REGS;
1995 } while (src != final);
1997 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp
1998 registers are needed.
2000 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3
2001 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every
2002 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */
2004 #define MAX_MOVE_REGS 4
2005 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2008 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
)
2009 rtx dest_reg
; /* register holding destination address */
2010 rtx src_reg
; /* register holding source address */
2011 int bytes
; /* # bytes to move */
2012 int align
; /* alignment */
2013 rtx orig_src
; /* original source for making a reg note */
2015 rtx dest_mem
= gen_rtx (MEM
, BLKmode
, dest_reg
);
2016 rtx src_mem
= gen_rtx (MEM
, BLKmode
, src_reg
);
2017 rtx align_rtx
= GEN_INT (align
);
2023 if (bytes
< 2*MAX_MOVE_BYTES
)
2026 leftover
= bytes
% MAX_MOVE_BYTES
;
2029 label
= gen_label_rtx ();
2030 final_src
= gen_reg_rtx (Pmode
);
2031 bytes_rtx
= GEN_INT (bytes
);
2035 emit_insn (gen_movsi (final_src
, bytes_rtx
));
2036 emit_insn (gen_addsi3 (final_src
, final_src
, src_reg
));
2039 emit_insn (gen_addsi3 (final_src
, src_reg
, bytes_rtx
));
2043 bytes_rtx
= GEN_INT (MAX_MOVE_BYTES
);
2044 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
, bytes_rtx
, align_rtx
));
2045 emit_insn (gen_addsi3 (src_reg
, src_reg
, bytes_rtx
));
2046 emit_insn (gen_addsi3 (dest_reg
, dest_reg
, bytes_rtx
));
2047 emit_insn (gen_cmpsi (src_reg
, final_src
));
2048 emit_jump_insn (gen_bne (label
));
2051 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
,
2057 /* Use a library function to move some bytes. */
2060 block_move_call (dest_reg
, src_reg
, bytes_rtx
)
2065 #ifdef TARGET_MEM_FUNCTIONS
2066 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "memcpy"), 0,
2072 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "bcopy"), 0,
2081 /* Expand string/block move operations.
2083 operands[0] is the pointer to the destination.
2084 operands[1] is the pointer to the source.
2085 operands[2] is the number of bytes to move.
2086 operands[3] is the alignment. */
2089 expand_block_move (operands
)
2092 rtx bytes_rtx
= operands
[2];
2093 rtx align_rtx
= operands
[3];
2094 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2095 int bytes
= (constp
? INTVAL (bytes_rtx
) : 0);
2096 int align
= INTVAL (align_rtx
);
2097 rtx orig_src
= operands
[1];
2101 if (constp
&& bytes
<= 0)
2104 if (align
> UNITS_PER_WORD
)
2105 align
= UNITS_PER_WORD
;
2107 /* Move the address into scratch registers. */
2108 dest_reg
= copy_addr_to_reg (XEXP (operands
[0], 0));
2109 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2112 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2115 else if (constp
&& bytes
<= 3*align
)
2116 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2119 else if (constp
&& bytes
<= 2*MAX_MOVE_BYTES
)
2120 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2121 gen_rtx (MEM
, BLKmode
, src_reg
),
2122 bytes_rtx
, align_rtx
));
2124 else if (constp
&& align
>= UNITS_PER_WORD
&& optimize
)
2125 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2127 else if (constp
&& optimize
)
2129 /* If the alignment is not word aligned, generate a test at
2130 runtime, to see whether things wound up aligned, and we
2131 can use the faster lw/sw instead ulw/usw. */
2133 rtx temp
= gen_reg_rtx (Pmode
);
2134 rtx aligned_label
= gen_label_rtx ();
2135 rtx join_label
= gen_label_rtx ();
2136 int leftover
= bytes
% MAX_MOVE_BYTES
;
2140 emit_insn (gen_iorsi3 (temp
, src_reg
, dest_reg
));
2141 emit_insn (gen_andsi3 (temp
, temp
, GEN_INT (UNITS_PER_WORD
-1)));
2142 emit_insn (gen_cmpsi (temp
, const0_rtx
));
2143 emit_jump_insn (gen_beq (aligned_label
));
2145 /* Unaligned loop. */
2146 block_move_loop (dest_reg
, src_reg
, bytes
, 1, orig_src
);
2147 emit_jump_insn (gen_jump (join_label
));
2151 emit_label (aligned_label
);
2152 block_move_loop (dest_reg
, src_reg
, bytes
, UNITS_PER_WORD
, orig_src
);
2153 emit_label (join_label
);
2155 /* Bytes at the end of the loop. */
2159 if (leftover
<= 3*align
)
2160 block_move_sequence (dest_reg
, src_reg
, leftover
, align
, orig_src
);
2164 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2165 gen_rtx (MEM
, BLKmode
, src_reg
),
2172 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2176 /* Emit load/stores for a small constant block_move.
2178 operands[0] is the memory address of the destination.
2179 operands[1] is the memory address of the source.
2180 operands[2] is the number of bytes to move.
2181 operands[3] is the alignment.
2182 operands[4] is a temp register.
2183 operands[5] is a temp register.
2185 operands[3+num_regs] is the last temp register.
2187 The block move type can be one of the following:
2188 BLOCK_MOVE_NORMAL Do all of the block move.
2189 BLOCK_MOVE_NOT_LAST Do all but the last store.
2190 BLOCK_MOVE_LAST Do just the last store. */
2193 output_block_move (insn
, operands
, num_regs
, move_type
)
2197 enum block_move_type move_type
;
2199 rtx dest_reg
= XEXP (operands
[0], 0);
2200 rtx src_reg
= XEXP (operands
[1], 0);
2201 int bytes
= INTVAL (operands
[2]);
2202 int align
= INTVAL (operands
[3]);
2205 int use_lwl_lwr
= FALSE
;
2206 int last_operand
= num_regs
+4;
2212 char *load
; /* load insn without nop */
2213 char *load_nop
; /* load insn with trailing nop */
2214 char *store
; /* store insn */
2215 char *final
; /* if last_store used: NULL or swr */
2216 char *last_store
; /* last store instruction */
2217 int offset
; /* current offset */
2218 enum machine_mode mode
; /* mode to use on (MEM) */
2221 /* Detect a bug in GCC, where it can give us a register
2222 the same as one of the addressing registers and reduce
2223 the number of registers available. */
2225 i
< last_operand
&& safe_regs
< (sizeof(xoperands
) / sizeof(xoperands
[0]));
2228 if (!reg_mentioned_p (operands
[i
], operands
[0])
2229 && !reg_mentioned_p (operands
[i
], operands
[1]))
2231 xoperands
[safe_regs
++] = operands
[i
];
2234 if (safe_regs
< last_operand
)
2236 xoperands
[0] = operands
[0];
2237 xoperands
[1] = operands
[1];
2238 xoperands
[2] = operands
[2];
2239 xoperands
[3] = operands
[3];
2240 return output_block_move (insn
, xoperands
, safe_regs
-4, move_type
);
2243 /* If we are given global or static addresses, and we would be
2244 emitting a few instructions, try to save time by using a
2245 temporary register for the pointer. */
2246 if (num_regs
> 2 && (bytes
> 2*align
|| move_type
!= BLOCK_MOVE_NORMAL
))
2248 if (CONSTANT_P (src_reg
))
2251 mips_count_memory_refs (operands
[1], 1);
2253 src_reg
= operands
[ 3 + num_regs
-- ];
2254 if (move_type
!= BLOCK_MOVE_LAST
)
2256 xoperands
[1] = operands
[1];
2257 xoperands
[0] = src_reg
;
2258 output_asm_insn ("la\t%0,%1", xoperands
);
2262 if (CONSTANT_P (dest_reg
))
2265 mips_count_memory_refs (operands
[0], 1);
2267 dest_reg
= operands
[ 3 + num_regs
-- ];
2268 if (move_type
!= BLOCK_MOVE_LAST
)
2270 xoperands
[1] = operands
[0];
2271 xoperands
[0] = dest_reg
;
2272 output_asm_insn ("la\t%0,%1", xoperands
);
2277 if (num_regs
> (sizeof (load_store
) / sizeof (load_store
[0])))
2278 num_regs
= (sizeof (load_store
) / sizeof (load_store
[0]));
2280 else if (num_regs
< 1)
2281 abort_with_insn (insn
, "Cannot do block move, not enough scratch registers");
2283 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& set_noreorder
++ == 0)
2284 output_asm_insn (".set\tnoreorder", operands
);
2288 load_store
[num
].offset
= offset
;
2290 if (bytes
>= UNITS_PER_WORD
&& align
>= UNITS_PER_WORD
)
2292 load_store
[num
].load
= "lw\t%0,%1";
2293 load_store
[num
].load_nop
= "lw\t%0,%1%#";
2294 load_store
[num
].store
= "sw\t%0,%1";
2295 load_store
[num
].last_store
= "sw\t%0,%1";
2296 load_store
[num
].final
= (char *)0;
2297 load_store
[num
].mode
= SImode
;
2298 offset
+= UNITS_PER_WORD
;
2299 bytes
-= UNITS_PER_WORD
;
2302 else if (bytes
>= UNITS_PER_WORD
)
2304 #if BYTES_BIG_ENDIAN
2305 load_store
[num
].load
= "lwl\t%0,%1\n\tlwr\t%0,%2";
2306 load_store
[num
].load_nop
= "lwl\t%0,%1\n\tlwr\t%0,%2%#";
2307 load_store
[num
].store
= "swl\t%0,%1\n\tswr\t%0,%2";
2308 load_store
[num
].last_store
= "swr\t%0,%2";
2309 load_store
[num
].final
= "swl\t%0,%1";
2311 load_store
[num
].load
= "lwl\t%0,%2\n\tlwr\t%0,%1";
2312 load_store
[num
].load_nop
= "lwl\t%0,%2\n\tlwr\t%0,%1%#";
2313 load_store
[num
].store
= "swl\t%0,%2\n\tswr\t%0,%1";
2314 load_store
[num
].last_store
= "swr\t%0,%1";
2315 load_store
[num
].final
= "swl\t%0,%2";
2317 load_store
[num
].mode
= SImode
;
2318 offset
+= UNITS_PER_WORD
;
2319 bytes
-= UNITS_PER_WORD
;
2323 else if (bytes
>= UNITS_PER_SHORT
&& align
>= UNITS_PER_SHORT
)
2325 load_store
[num
].load
= "lh\t%0,%1";
2326 load_store
[num
].load_nop
= "lh\t%0,%1%#";
2327 load_store
[num
].store
= "sh\t%0,%1";
2328 load_store
[num
].last_store
= "sh\t%0,%1";
2329 load_store
[num
].final
= (char *)0;
2330 load_store
[num
].offset
= offset
;
2331 load_store
[num
].mode
= HImode
;
2332 offset
+= UNITS_PER_SHORT
;
2333 bytes
-= UNITS_PER_SHORT
;
2338 load_store
[num
].load
= "lb\t%0,%1";
2339 load_store
[num
].load_nop
= "lb\t%0,%1%#";
2340 load_store
[num
].store
= "sb\t%0,%1";
2341 load_store
[num
].last_store
= "sb\t%0,%1";
2342 load_store
[num
].final
= (char *)0;
2343 load_store
[num
].mode
= QImode
;
2348 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2350 dslots_load_total
++;
2351 dslots_load_filled
++;
2353 if (CONSTANT_P (src_reg
))
2354 mips_count_memory_refs (src_reg
, 1);
2356 if (CONSTANT_P (dest_reg
))
2357 mips_count_memory_refs (dest_reg
, 1);
2360 /* Emit load/stores now if we have run out of registers or are
2361 at the end of the move. */
2363 if (++num
== num_regs
|| bytes
== 0)
2365 /* If only load/store, we need a NOP after the load. */
2368 load_store
[0].load
= load_store
[0].load_nop
;
2369 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2370 dslots_load_filled
--;
2373 if (move_type
!= BLOCK_MOVE_LAST
)
2375 for (i
= 0; i
< num
; i
++)
2382 if (GET_MODE (operands
[i
+4]) != load_store
[i
].mode
)
2383 operands
[i
+4] = gen_rtx (REG
, load_store
[i
].mode
, REGNO (operands
[i
+4]));
2385 offset
= load_store
[i
].offset
;
2386 xoperands
[0] = operands
[i
+4];
2387 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2388 plus_constant (src_reg
, offset
));
2391 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2392 plus_constant (src_reg
, UNITS_PER_WORD
-1+offset
));
2394 output_asm_insn (load_store
[i
].load
, xoperands
);
2398 for (i
= 0; i
< num
; i
++)
2400 int last_p
= (i
== num
-1 && bytes
== 0);
2401 int offset
= load_store
[i
].offset
;
2403 xoperands
[0] = operands
[i
+4];
2404 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2405 plus_constant (dest_reg
, offset
));
2409 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2410 plus_constant (dest_reg
, UNITS_PER_WORD
-1+offset
));
2412 if (move_type
== BLOCK_MOVE_NORMAL
)
2413 output_asm_insn (load_store
[i
].store
, xoperands
);
2415 else if (move_type
== BLOCK_MOVE_NOT_LAST
)
2418 output_asm_insn (load_store
[i
].store
, xoperands
);
2420 else if (load_store
[i
].final
!= (char *)0)
2421 output_asm_insn (load_store
[i
].final
, xoperands
);
2425 output_asm_insn (load_store
[i
].last_store
, xoperands
);
2428 num
= 0; /* reset load_store */
2429 use_lwl_lwr
= FALSE
; /* reset whether or not we used lwl/lwr */
2433 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& --set_noreorder
== 0)
2434 output_asm_insn (".set\treorder", operands
);
2440 /* Argument support functions. */
2442 /* Initialize CUMULATIVE_ARGS for a function. */
2445 init_cumulative_args (cum
, fntype
, libname
)
2446 CUMULATIVE_ARGS
*cum
; /* argument info to initialize */
2447 tree fntype
; /* tree ptr for function decl */
2448 rtx libname
; /* SYMBOL_REF of library name or 0 */
2450 static CUMULATIVE_ARGS zero_cum
;
2451 tree param
, next_param
;
2453 if (TARGET_DEBUG_E_MODE
)
2455 fprintf (stderr
, "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype
);
2457 fputc ('\n', stderr
);
2461 tree ret_type
= TREE_TYPE (fntype
);
2462 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
2463 tree_code_name
[ (int)TREE_CODE (fntype
) ],
2464 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
2470 /* Determine if this function has variable arguments. This is
2471 indicated by the last argument being 'void_type_mode' if there
2472 are no variable arguments. The standard MIPS calling sequence
2473 passes all arguments in the general purpose registers in this
2476 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
2480 next_param
= TREE_CHAIN (param
);
2481 if (next_param
== (tree
)0 && TREE_VALUE (param
) != void_type_node
)
2482 cum
->gp_reg_found
= 1;
2486 /* Advance the argument to the next argument position. */
2489 function_arg_advance (cum
, mode
, type
, named
)
2490 CUMULATIVE_ARGS
*cum
; /* current arg information */
2491 enum machine_mode mode
; /* current arg mode */
2492 tree type
; /* type of the argument or 0 if lib support */
2493 int named
; /* whether or not the argument was named */
2495 if (TARGET_DEBUG_E_MODE
)
2497 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n\n",
2498 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2505 error ("Illegal mode given to function_arg_advance");
2512 cum
->gp_reg_found
= 1;
2513 cum
->arg_words
+= (int_size_in_bytes (type
) + 3) / 4;
2521 cum
->arg_words
+= 2;
2525 cum
->gp_reg_found
= 1;
2526 cum
->arg_words
+= 2;
2532 cum
->gp_reg_found
= 1;
2538 /* Return a RTL expression containing the register for the given mode,
2539 or 0 if the argument is too be passed on the stack. */
2542 function_arg (cum
, mode
, type
, named
)
2543 CUMULATIVE_ARGS
*cum
; /* current arg information */
2544 enum machine_mode mode
; /* current arg mode */
2545 tree type
; /* type of the argument or 0 if lib support */
2546 int named
; /* != 0 for normal args, == 0 for ... args */
2551 int struct_p
= ((type
!= (tree
)0)
2552 && (TREE_CODE (type
) == RECORD_TYPE
2553 || TREE_CODE (type
) == UNION_TYPE
));
2555 if (TARGET_DEBUG_E_MODE
)
2557 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ",
2558 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2564 error ("Illegal mode given to function_arg");
2568 if (cum
->gp_reg_found
|| cum
->arg_number
>= 2)
2569 regbase
= GP_ARG_FIRST
;
2571 regbase
= (TARGET_SOFT_FLOAT
) ? GP_ARG_FIRST
: FP_ARG_FIRST
;
2572 if (cum
->arg_words
== 1) /* first arg was float */
2573 bias
= 1; /* use correct reg */
2579 cum
->arg_words
+= (cum
->arg_words
& 1);
2580 regbase
= (cum
->gp_reg_found
|| TARGET_SOFT_FLOAT
)
2586 if (type
!= (tree
)0 && TYPE_ALIGN (type
) > BITS_PER_WORD
)
2587 cum
->arg_words
+= (cum
->arg_words
& 1);
2589 regbase
= GP_ARG_FIRST
;
2596 regbase
= GP_ARG_FIRST
;
2600 cum
->arg_words
+= (cum
->arg_words
& 1);
2601 regbase
= GP_ARG_FIRST
;
2604 if (cum
->arg_words
>= MAX_ARGS_IN_REGISTERS
)
2606 if (TARGET_DEBUG_E_MODE
)
2607 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
2616 ret
= gen_rtx (REG
, mode
, regbase
+ cum
->arg_words
+ bias
);
2618 if (TARGET_DEBUG_E_MODE
)
2619 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ cum
->arg_words
+ bias
],
2620 struct_p
? ", [struct]" : "");
2622 /* The following is a hack in order to pass 1 byte structures
2623 the same way that the MIPS compiler does (namely by passing
2624 the structure in the high byte or half word of the register).
2625 This also makes varargs work. If we have such a structure,
2626 we save the adjustment RTL, and the call define expands will
2627 emit them. For the VOIDmode argument (argument after the
2628 last real argument, pass back a parallel vector holding each
2629 of the adjustments. */
2631 if (struct_p
&& (mode
== QImode
|| mode
== HImode
))
2633 rtx amount
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (mode
));
2634 rtx reg
= gen_rtx (REG
, SImode
, regbase
+ cum
->arg_words
+ bias
);
2635 cum
->adjust
[ cum
->num_adjusts
++ ] = gen_ashlsi3 (reg
, reg
, amount
);
2639 if (mode
== VOIDmode
&& cum
->num_adjusts
> 0)
2640 ret
= gen_rtx (PARALLEL
, VOIDmode
, gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
2647 function_arg_partial_nregs (cum
, mode
, type
, named
)
2648 CUMULATIVE_ARGS
*cum
; /* current arg information */
2649 enum machine_mode mode
; /* current arg mode */
2650 tree type
; /* type of the argument or 0 if lib support */
2651 int named
; /* != 0 for normal args, == 0 for ... args */
2653 if (mode
== BLKmode
&& cum
->arg_words
< MAX_ARGS_IN_REGISTERS
)
2655 int words
= (int_size_in_bytes (type
) + 3) / 4;
2657 if (words
+ cum
->arg_words
<= MAX_ARGS_IN_REGISTERS
)
2658 return 0; /* structure fits in registers */
2660 if (TARGET_DEBUG_E_MODE
)
2661 fprintf (stderr
, "function_arg_partial_nregs = %d\n",
2662 MAX_ARGS_IN_REGISTERS
- cum
->arg_words
);
2664 return MAX_ARGS_IN_REGISTERS
- cum
->arg_words
;
2667 else if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
-1)
2669 if (TARGET_DEBUG_E_MODE
)
2670 fprintf (stderr
, "function_arg_partial_nregs = 1\n");
2679 /* Print the options used in the assembly file. */
2681 static struct {char *name
; int value
;} target_switches
[]
2692 int mask
= TARGET_DEFAULT
;
2694 /* Allow assembly language comparisons with -mdebug eliminating the
2695 compiler version number and switch lists. */
2697 if (TARGET_DEBUG_MODE
)
2700 fprintf (out
, "\n # %s %s", language_string
, version_string
);
2701 #ifdef TARGET_VERSION_INTERNAL
2702 TARGET_VERSION_INTERNAL (out
);
2705 fprintf (out
, " compiled by GNU C\n\n");
2707 fprintf (out
, " compiled by CC\n\n");
2710 fprintf (out
, " # Cc1 defaults:");
2712 for (j
= 0; j
< sizeof target_switches
/ sizeof target_switches
[0]; j
++)
2714 if (target_switches
[j
].name
[0] != '\0'
2715 && target_switches
[j
].value
> 0
2716 && (target_switches
[j
].value
& mask
) == target_switches
[j
].value
)
2718 mask
&= ~ target_switches
[j
].value
;
2719 len
= strlen (target_switches
[j
].name
) + 1;
2720 if (len
+ line_len
> 79)
2723 fputs ("\n #", out
);
2725 fprintf (out
, " -m%s", target_switches
[j
].name
);
2730 fprintf (out
, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):",
2731 mips_section_threshold
, mips_cpu_string
, mips_isa
);
2734 for (p
= &save_argv
[1]; *p
!= (char *)0; p
++)
2739 len
= strlen (arg
) + 1;
2740 if (len
+ line_len
> 79)
2743 fputs ("\n #", out
);
2745 fprintf (out
, " %s", *p
);
2750 fputs ("\n\n", out
);
2754 /* Abort after printing out a specific insn. */
2757 abort_with_insn (insn
, reason
)
2766 /* Write a message to stderr (for use in macros expanded in files that do not
2767 include stdio.h). */
2773 fprintf (stderr
, s
, s1
, s2
);
2783 fprintf (stderr
, "compiling '%s' in '%s'\n",
2784 (current_function_name
!= (char *)0) ? current_function_name
: "<toplevel>",
2785 (current_function_file
!= (char *)0) ? current_function_file
: "<no file>");
2788 #endif /* SIGINFO */
2791 /* Set up the threshold for data to go into the small data area, instead
2792 of the normal data area, and detect any conflicts in the switches. */
2797 register int i
, start
;
2799 register enum machine_mode mode
;
2801 mips_section_threshold
= (g_switch_set
) ? g_switch_value
: MIPS_DEFAULT_GVALUE
;
2803 /* Identify the processor type */
2804 if (mips_cpu_string
== (char *)0
2805 || !strcmp (mips_cpu_string
, "default")
2806 || !strcmp (mips_cpu_string
, "DEFAULT"))
2808 mips_cpu_string
= "default";
2809 mips_cpu
= PROCESSOR_DEFAULT
;
2814 char *p
= mips_cpu_string
;
2816 if (*p
== 'r' || *p
== 'R')
2819 /* Since there is no difference between a R2000 and R3000 in
2820 terms of the scheduler, we collapse them into just an R3000. */
2822 mips_cpu
= PROCESSOR_DEFAULT
;
2826 if (!strcmp (p
, "2000") || !strcmp (p
, "2k") || !strcmp (p
, "2K"))
2827 mips_cpu
= PROCESSOR_R3000
;
2831 if (!strcmp (p
, "3000") || !strcmp (p
, "3k") || !strcmp (p
, "3K"))
2832 mips_cpu
= PROCESSOR_R3000
;
2836 if (!strcmp (p
, "4000") || !strcmp (p
, "4k") || !strcmp (p
, "4K"))
2837 mips_cpu
= PROCESSOR_R4000
;
2841 if (!strcmp (p
, "6000") || !strcmp (p
, "6k") || !strcmp (p
, "6K"))
2842 mips_cpu
= PROCESSOR_R6000
;
2846 if (mips_cpu
== PROCESSOR_DEFAULT
)
2848 error ("bad value (%s) for -mcpu= switch", mips_cpu_string
);
2849 mips_cpu_string
= "default";
2853 /* Now get the architectural level. */
2854 if (mips_isa_string
== (char *)0)
2857 else if (isdigit (*mips_isa_string
))
2858 mips_isa
= atoi (mips_isa_string
);
2862 error ("bad value (%s) for -mips switch", mips_isa_string
);
2866 if (mips_isa
< 0 || mips_isa
> 3)
2867 error ("-mips%d not supported", mips_isa
);
2869 else if (mips_isa
> 1
2870 && (mips_cpu
== PROCESSOR_DEFAULT
|| mips_cpu
== PROCESSOR_R3000
))
2871 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
2873 else if (mips_cpu
== PROCESSOR_R6000
&& mips_isa
> 2)
2874 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
2876 /* make sure sizes of ints/longs/etc. are ok */
2880 fatal ("Only the r4000 can support 64 bit ints");
2882 else if (TARGET_LONG64
)
2883 fatal ("Only the r4000 can support 64 bit longs");
2885 else if (TARGET_LLONG128
)
2886 fatal ("Only the r4000 can support 128 bit long longs");
2888 else if (TARGET_FLOAT64
)
2889 fatal ("Only the r4000 can support 64 bit fp registers");
2891 else if (TARGET_INT64
|| TARGET_LONG64
|| TARGET_LLONG128
|| TARGET_FLOAT64
)
2892 warning ("r4000 64/128 bit types not yet supported");
2894 /* Tell halfpic.c that we have half-pic code if we do. */
2895 if (TARGET_HALF_PIC
)
2898 /* -mrnames says to use the MIPS software convention for register
2899 names instead of the hardware names (ie, a0 instead of $4).
2900 We do this by switching the names in mips_reg_names, which the
2901 reg_names points into via the REGISTER_NAMES macro. */
2903 if (TARGET_NAME_REGS
)
2907 target_flags
&= ~ MASK_NAME_REGS
;
2908 error ("Gas does not support the MIPS software register name convention.");
2911 bcopy ((char *) mips_sw_reg_names
, (char *) mips_reg_names
, sizeof (mips_reg_names
));
2914 /* If this is OSF/1, set up a SIGINFO handler so we can see what function
2915 is currently being compiled. */
2917 if (getenv ("GCC_SIGINFO") != (char *)0)
2919 struct sigaction action
;
2920 action
.sa_handler
= siginfo
;
2922 action
.sa_flags
= SA_RESTART
;
2923 sigaction (SIGINFO
, &action
, (struct sigaction
*)0);
2928 #if defined(ultrix) || defined(__ultrix) || defined(__OSF1__) || defined(__osf__) || defined(osf)
2929 /* If -mstats and -quiet, make stderr line buffered. */
2930 if (quiet_flag
&& TARGET_STATS
)
2931 setvbuf (stderr
, (char *)0, _IOLBF
, BUFSIZ
);
2935 /* Set up the classification arrays now. */
2936 mips_rtx_classify
[(int)PLUS
] = CLASS_ADD_OP
;
2937 mips_rtx_classify
[(int)MINUS
] = CLASS_ADD_OP
;
2938 mips_rtx_classify
[(int)DIV
] = CLASS_DIVMOD_OP
;
2939 mips_rtx_classify
[(int)MOD
] = CLASS_DIVMOD_OP
;
2940 mips_rtx_classify
[(int)UDIV
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
2941 mips_rtx_classify
[(int)UMOD
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
2942 mips_rtx_classify
[(int)EQ
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
2943 mips_rtx_classify
[(int)NE
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
2944 mips_rtx_classify
[(int)GT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2945 mips_rtx_classify
[(int)GE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2946 mips_rtx_classify
[(int)LT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2947 mips_rtx_classify
[(int)LE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2948 mips_rtx_classify
[(int)GTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2949 mips_rtx_classify
[(int)GEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2950 mips_rtx_classify
[(int)LTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2951 mips_rtx_classify
[(int)LEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2953 mips_print_operand_punct
['?'] = TRUE
;
2954 mips_print_operand_punct
['#'] = TRUE
;
2955 mips_print_operand_punct
['&'] = TRUE
;
2956 mips_print_operand_punct
['!'] = TRUE
;
2957 mips_print_operand_punct
['*'] = TRUE
;
2958 mips_print_operand_punct
['@'] = TRUE
;
2959 mips_print_operand_punct
['.'] = TRUE
;
2960 mips_print_operand_punct
['('] = TRUE
;
2961 mips_print_operand_punct
[')'] = TRUE
;
2962 mips_print_operand_punct
['['] = TRUE
;
2963 mips_print_operand_punct
[']'] = TRUE
;
2964 mips_print_operand_punct
['<'] = TRUE
;
2965 mips_print_operand_punct
['>'] = TRUE
;
2966 mips_print_operand_punct
['{'] = TRUE
;
2967 mips_print_operand_punct
['}'] = TRUE
;
2969 mips_char_to_class
['d'] = GR_REGS
;
2970 mips_char_to_class
['f'] = ((TARGET_HARD_FLOAT
) ? FP_REGS
: NO_REGS
);
2971 mips_char_to_class
['h'] = HI_REG
;
2972 mips_char_to_class
['l'] = LO_REG
;
2973 mips_char_to_class
['x'] = MD_REGS
;
2974 mips_char_to_class
['y'] = GR_REGS
;
2975 mips_char_to_class
['z'] = ST_REGS
;
2977 /* Set up array to map GCC register number to debug register number.
2978 Ignore the special purpose register numbers. */
2980 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2981 mips_dbx_regno
[i
] = -1;
2983 start
= GP_DBX_FIRST
- GP_REG_FIRST
;
2984 for (i
= GP_REG_FIRST
; i
<= GP_REG_LAST
; i
++)
2985 mips_dbx_regno
[i
] = i
+ start
;
2987 start
= FP_DBX_FIRST
- FP_REG_FIRST
;
2988 for (i
= FP_REG_FIRST
; i
<= FP_REG_LAST
; i
++)
2989 mips_dbx_regno
[i
] = i
+ start
;
2991 /* Set up array giving whether a given register can hold a given mode.
2992 At present, restrict ints from being in FP registers, because reload
2993 is a little enthusiastic about storing extra values in FP registers,
2994 and this is not good for things like OS kernels. Also, due to the
2995 mandatory delay, it is as fast to load from cached memory as to move
2996 from the FP register. */
2998 for (mode
= VOIDmode
;
2999 mode
!= MAX_MACHINE_MODE
;
3000 mode
= (enum machine_mode
)((int)mode
+ 1))
3002 register int size
= GET_MODE_SIZE (mode
);
3003 register enum mode_class
class = GET_MODE_CLASS (mode
);
3005 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
3009 if (mode
== CC_FPmode
|| mode
== CC_REV_FPmode
)
3010 temp
= (regno
== FPSW_REGNUM
);
3012 else if (GP_REG_P (regno
))
3013 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
3015 else if (FP_REG_P (regno
))
3016 temp
= ((TARGET_FLOAT64
|| ((regno
& 1) == 0))
3017 && (class == MODE_FLOAT
3018 || class == MODE_COMPLEX_FLOAT
3019 || (TARGET_DEBUG_H_MODE
&& class == MODE_INT
)));
3021 else if (MD_REG_P (regno
))
3022 temp
= (mode
== SImode
|| (regno
== MD_REG_FIRST
&& mode
== DImode
));
3027 mips_hard_regno_mode_ok
[(int)mode
][regno
] = temp
;
3034 * The MIPS debug format wants all automatic variables and arguments
3035 * to be in terms of the virtual frame pointer (stack pointer before
3036 * any adjustment in the function), while the MIPS 3.0 linker wants
3037 * the frame pointer to be the stack pointer after the initial
3038 * adjustment. So, we do the adjustment here. The arg pointer (which
3039 * is eliminated) points to the virtual frame pointer, while the frame
3040 * pointer (which may be eliminated) points to the stack pointer after
3041 * the initial adjustments.
3045 mips_debugger_offset (addr
, offset
)
3049 rtx offset2
= const0_rtx
;
3050 rtx reg
= eliminate_constant_term (addr
, &offset2
);
3053 offset
= INTVAL (offset2
);
3055 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
)
3057 int frame_size
= (!current_frame_info
.initialized
)
3058 ? compute_frame_size (get_frame_size ())
3059 : current_frame_info
.total_size
;
3061 offset
= offset
- frame_size
;
3063 /* sdbout_parms does not want this to crash for unrecognized cases. */
3065 else if (reg
!= arg_pointer_rtx
)
3066 abort_with_insn (addr
, "mips_debugger_offset called with non stack/frame/arg pointer.");
3073 /* A C compound statement to output to stdio stream STREAM the
3074 assembler syntax for an instruction operand X. X is an RTL
3077 CODE is a value that can be used to specify one of several ways
3078 of printing the operand. It is used when identical operands
3079 must be printed differently depending on the context. CODE
3080 comes from the `%' specification that was used to request
3081 printing of the operand. If the specification was just `%DIGIT'
3082 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3083 is the ASCII code for LTR.
3085 If X is a register, this macro should print the register's name.
3086 The names can be found in an array `reg_names' whose type is
3087 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3089 When the machine description has a specification `%PUNCT' (a `%'
3090 followed by a punctuation character), this macro is called with
3091 a null pointer for X and the punctuation character for CODE.
3093 The MIPS specific codes are:
3095 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
3096 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
3097 'd' output integer constant in decimal,
3098 'z' if the operand is 0, use $0 instead of normal operand.
3099 'D' print second register of double-word register operand.
3100 'L' print low-order register of double-word register operand.
3101 'M' print high-order register of double-word register operand.
3102 'C' print part of opcode for a branch condition.
3103 'N' print part of opcode for a branch condition, inverted.
3104 '(' Turn on .set noreorder
3105 ')' Turn on .set reorder
3106 '[' Turn on .set noat
3108 '<' Turn on .set nomacro
3109 '>' Turn on .set macro
3110 '{' Turn on .set volatile (not GAS)
3111 '}' Turn on .set novolatile (not GAS)
3112 '&' Turn on .set noreorder if filling delay slots
3113 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
3114 '!' Turn on .set nomacro if filling delay slots
3115 '#' Print nop if in a .set noreorder section.
3116 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3117 '@' Print the name of the assembler temporary register (at or $1).
3118 '.' Print the name of the register with a hard-wired zero (zero or $0). */
3121 print_operand (file
, op
, letter
)
3122 FILE *file
; /* file to write to */
3123 rtx op
; /* operand to print */
3124 int letter
; /* %<letter> or 0 */
3126 register enum rtx_code code
;
3128 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3133 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3137 if (mips_branch_likely
)
3142 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3146 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3150 if (final_sequence
!= 0 && set_noreorder
++ == 0)
3151 fputs (".set\tnoreorder\n\t", file
);
3155 if (final_sequence
!= 0)
3157 if (set_noreorder
++ == 0)
3158 fputs (".set\tnoreorder\n\t", file
);
3160 if (set_nomacro
++ == 0)
3161 fputs (".set\tnomacro\n\t", file
);
3166 if (final_sequence
!= 0 && set_nomacro
++ == 0)
3167 fputs ("\n\t.set\tnomacro", file
);
3171 if (set_noreorder
!= 0)
3172 fputs ("\n\tnop", file
);
3174 else if (TARGET_GAS
|| TARGET_STATS
)
3175 fputs ("\n\t#nop", file
);
3180 if (set_noreorder
++ == 0)
3181 fputs (".set\tnoreorder\n\t", file
);
3185 if (set_noreorder
== 0)
3186 error ("internal error: %%) found without a %%( in assembler pattern");
3188 else if (--set_noreorder
== 0)
3189 fputs ("\n\t.set\treorder", file
);
3194 if (set_noat
++ == 0)
3195 fputs (".set\tnoat\n\t", file
);
3200 error ("internal error: %%] found without a %%[ in assembler pattern");
3202 else if (--set_noat
== 0)
3203 fputs ("\n\t.set\tat", file
);
3208 if (set_nomacro
++ == 0)
3209 fputs (".set\tnomacro\n\t", file
);
3213 if (set_nomacro
== 0)
3214 error ("internal error: %%> found without a %%< in assembler pattern");
3216 else if (--set_nomacro
== 0)
3217 fputs ("\n\t.set\tmacro", file
);
3222 if (set_volatile
++ == 0)
3223 fprintf (file
, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS
) ? "" : "#");
3227 if (set_volatile
== 0)
3228 error ("internal error: %%} found without a %%{ in assembler pattern");
3230 else if (--set_volatile
== 0)
3231 fprintf (file
, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS
) ? "" : "#");
3240 error ("PRINT_OPERAND null pointer");
3244 code
= GET_CODE (op
);
3248 case EQ
: fputs ("eq", file
); break;
3249 case NE
: fputs ("ne", file
); break;
3250 case GT
: fputs ("gt", file
); break;
3251 case GE
: fputs ("ge", file
); break;
3252 case LT
: fputs ("lt", file
); break;
3253 case LE
: fputs ("le", file
); break;
3254 case GTU
: fputs ("gtu", file
); break;
3255 case GEU
: fputs ("geu", file
); break;
3256 case LTU
: fputs ("ltu", file
); break;
3257 case LEU
: fputs ("leu", file
); break;
3260 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%C");
3263 else if (letter
== 'N')
3266 case EQ
: fputs ("ne", file
); break;
3267 case NE
: fputs ("eq", file
); break;
3268 case GT
: fputs ("le", file
); break;
3269 case GE
: fputs ("lt", file
); break;
3270 case LT
: fputs ("ge", file
); break;
3271 case LE
: fputs ("gt", file
); break;
3272 case GTU
: fputs ("leu", file
); break;
3273 case GEU
: fputs ("ltu", file
); break;
3274 case LTU
: fputs ("geu", file
); break;
3275 case LEU
: fputs ("gtu", file
); break;
3278 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%N");
3281 else if (code
== REG
)
3283 register int regnum
= REGNO (op
);
3286 regnum
+= MOST_SIGNIFICANT_WORD
;
3288 else if (letter
== 'L')
3289 regnum
+= LEAST_SIGNIFICANT_WORD
;
3291 else if (letter
== 'D')
3294 fprintf (file
, "%s", reg_names
[regnum
]);
3297 else if (code
== MEM
)
3298 output_address (XEXP (op
, 0));
3300 else if (code
== CONST_DOUBLE
)
3302 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
3303 union { double d
; int i
[2]; } u
;
3304 u
.i
[0] = CONST_DOUBLE_LOW (op
);
3305 u
.i
[1] = CONST_DOUBLE_HIGH (op
);
3306 if (GET_MODE (op
) == SFmode
)
3312 fprintf (file
, "%.20e", u
.d
);
3314 fatal ("CONST_DOUBLE found in cross compilation");
3318 else if ((letter
== 'x') && (GET_CODE(op
) == CONST_INT
))
3319 fprintf (file
, "0x%04x", 0xffff & (INTVAL(op
)));
3321 else if ((letter
== 'X') && (GET_CODE(op
) == CONST_INT
))
3322 fprintf (file
, "0x%08x", INTVAL(op
));
3324 else if ((letter
== 'd') && (GET_CODE(op
) == CONST_INT
))
3325 fprintf (file
, "%d", (INTVAL(op
)));
3327 else if (letter
== 'z'
3328 && (GET_CODE (op
) == CONST_INT
)
3329 && INTVAL (op
) == 0)
3330 fputs (reg_names
[GP_REG_FIRST
], file
);
3332 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3333 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter
);
3336 output_addr_const (file
, op
);
3340 /* A C compound statement to output to stdio stream STREAM the
3341 assembler syntax for an instruction operand that is a memory
3342 reference whose address is ADDR. ADDR is an RTL expression.
3344 On some machines, the syntax for a symbolic address depends on
3345 the section that the address refers to. On these machines,
3346 define the macro `ENCODE_SECTION_INFO' to store the information
3347 into the `symbol_ref', and then check for it here. */
3350 print_operand_address (file
, addr
)
3355 error ("PRINT_OPERAND_ADDRESS, null pointer");
3358 switch (GET_CODE (addr
))
3361 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #1");
3365 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3366 abort_with_insn (addr
, "Arg pointer not eliminated.");
3368 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
3373 register rtx reg
= (rtx
)0;
3374 register rtx offset
= (rtx
)0;
3375 register rtx arg0
= XEXP (addr
, 0);
3376 register rtx arg1
= XEXP (addr
, 1);
3378 if (GET_CODE (arg0
) == REG
)
3382 if (GET_CODE (offset
) == REG
)
3383 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
3385 else if (GET_CODE (arg1
) == REG
)
3390 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
3392 output_addr_const (file
, addr
);
3396 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3398 if (!CONSTANT_P (offset
))
3399 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #2");
3401 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3402 abort_with_insn (addr
, "Arg pointer not eliminated.");
3404 output_addr_const (file
, offset
);
3405 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3413 output_addr_const (file
, addr
);
3419 /* If optimizing for the global pointer, keep track of all of
3420 the externs, so that at the end of the file, we can emit
3421 the appropriate .extern declaration for them, before writing
3422 out the text section. We assume that all names passed to
3423 us are in the permanent obstack, so that they will be valid
3424 at the end of the compilation.
3426 If we have -G 0, or the extern size is unknown, don't bother
3427 emitting the .externs. */
3430 mips_output_external (file
, decl
, name
)
3435 register struct extern_list
*p
;
3439 && mips_section_threshold
!= 0
3440 && ((TREE_CODE (decl
)) != FUNCTION_DECL
)
3441 && ((len
= int_size_in_bytes (TREE_TYPE (decl
))) > 0))
3443 p
= (struct extern_list
*)permalloc ((long) sizeof (struct extern_list
));
3444 p
->next
= extern_head
;
3453 /* Compute a string to use as a temporary file name. */
3459 char *base
= getenv ("TMPDIR");
3462 if (base
== (char *)0)
3465 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
3469 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
3475 len
= strlen (base
);
3476 temp_filename
= (char *) alloca (len
+ sizeof("/ccXXXXXX"));
3477 strcpy (temp_filename
, base
);
3478 if (len
> 0 && temp_filename
[len
-1] != '/')
3479 temp_filename
[len
++] = '/';
3481 strcpy (temp_filename
+ len
, "ccXXXXXX");
3482 mktemp (temp_filename
);
3484 stream
= fopen (temp_filename
, "w+");
3486 pfatal_with_name (temp_filename
);
3488 unlink (temp_filename
);
3493 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out
3494 for .file's that start within a function. If we are smuggling stabs, try to
3495 put out a MIPS ECOFF file and a stab. */
3498 mips_output_filename (stream
, name
)
3502 static int first_time
= TRUE
;
3503 char ltext_label_name
[100];
3509 current_function_file
= name
;
3510 fprintf (stream
, "\t.file\t%d \"%s\"\n", num_source_filenames
, name
);
3511 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3512 fprintf (stream
, "\t#@stabs\n");
3515 else if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3517 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
3518 fprintf (stream
, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP
,
3519 name
, N_SOL
, <ext_label_name
[1]);
3522 else if (name
!= current_function_file
3523 && strcmp (name
, current_function_file
) != 0)
3525 if (inside_function
&& !TARGET_GAS
)
3527 if (!file_in_function_warning
)
3529 file_in_function_warning
= TRUE
;
3530 ignore_line_number
= TRUE
;
3531 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line");
3534 fprintf (stream
, "\t#.file\t%d \"%s\"\n", num_source_filenames
, name
);
3540 current_function_file
= name
;
3541 fprintf (stream
, "\t.file\t%d \"%s\"\n", num_source_filenames
, name
);
3547 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
3548 as well as a .loc, since it is possible that MIPS ECOFF might not be
3549 able to represent the location for inlines that come from a different
3553 mips_output_lineno (stream
, line
)
3557 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3560 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3561 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
3566 fprintf (stream
, "\n\t%s.loc\t%d %d\n",
3567 (ignore_line_number
) ? "#" : "",
3568 num_source_filenames
, line
);
3570 LABEL_AFTER_LOC (stream
);
3575 /* If defined, a C statement to be executed just prior to the
3576 output of assembler code for INSN, to modify the extracted
3577 operands so they will be output differently.
3579 Here the argument OPVEC is the vector containing the operands
3580 extracted from INSN, and NOPERANDS is the number of elements of
3581 the vector which contain meaningful data for this insn. The
3582 contents of this vector are what will be used to convert the
3583 insn template into assembler code, so you can change the
3584 assembler output by changing the contents of the vector.
3586 We use it to check if the current insn needs a nop in front of it
3587 because of load delays, and also to update the delay slot
3591 final_prescan_insn (insn
, opvec
, noperands
)
3596 if (dslots_number_nops
> 0)
3598 rtx pattern
= PATTERN (insn
);
3599 int length
= get_attr_length (insn
);
3601 /* Do we need to emit a NOP? */
3603 || (mips_load_reg
!= (rtx
)0 && reg_mentioned_p (mips_load_reg
, pattern
))
3604 || (mips_load_reg2
!= (rtx
)0 && reg_mentioned_p (mips_load_reg2
, pattern
))
3605 || (mips_load_reg3
!= (rtx
)0 && reg_mentioned_p (mips_load_reg3
, pattern
))
3606 || (mips_load_reg4
!= (rtx
)0 && reg_mentioned_p (mips_load_reg4
, pattern
)))
3607 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
3610 dslots_load_filled
++;
3612 while (--dslots_number_nops
> 0)
3613 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
3615 mips_load_reg
= (rtx
)0;
3616 mips_load_reg2
= (rtx
)0;
3617 mips_load_reg3
= (rtx
)0;
3618 mips_load_reg4
= (rtx
)0;
3620 if (set_noreorder
&& --set_noreorder
== 0)
3621 fputs ("\t.set\treorder\n", asm_out_file
);
3626 enum rtx_code code
= GET_CODE (insn
);
3627 if (code
== JUMP_INSN
|| code
== CALL_INSN
)
3628 dslots_jump_total
++;
3633 /* Output at beginning of assembler file.
3634 If we are optimizing to use the global pointer, create a temporary
3635 file to hold all of the text stuff, and write it out to the end.
3636 This is needed because the MIPS assembler is evidently one pass,
3637 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata
3638 declaration when the code is processed, it generates a two
3639 instruction sequence. */
3642 mips_asm_file_start (stream
)
3645 ASM_OUTPUT_SOURCE_FILENAME (stream
, main_input_filename
);
3647 /* Versions of the MIPS assembler before 2.20 generate errors
3648 if a branch inside of a .set noreorder section jumps to a
3649 label outside of the .set noreorder section. Revision 2.20
3650 just set nobopt silently rather than fixing the bug. */
3652 if (TARGET_MIPS_AS
&& optimize
&& flag_delayed_branch
)
3653 fprintf (stream
, "\t.set\tnobopt\n");
3655 /* Generate the pseudo ops that the Pyramid based System V.4 wants. */
3656 if (TARGET_ABICALLS
)
3657 fprintf (stream
, "\t.abicalls\n");
3661 asm_out_data_file
= stream
;
3662 asm_out_text_file
= make_temp_file ();
3665 asm_out_data_file
= asm_out_text_file
= stream
;
3667 if (TARGET_NAME_REGS
)
3668 fprintf (asm_out_file
, "#include <regdef.h>\n");
3670 print_options (stream
);
3674 /* If we are optimizing the global pointer, emit the text section now
3675 and any small externs which did not have .comm, etc that are
3676 needed. Also, give a warning if the data area is more than 32K and
3677 -pic because 3 instructions are needed to reference the data
3681 mips_asm_file_end (file
)
3686 struct extern_list
*p
;
3690 HALF_PIC_FINISH (file
);
3697 for (p
= extern_head
; p
!= 0; p
= p
->next
)
3699 name_tree
= get_identifier (p
->name
);
3701 /* Positively ensure only one .extern for any given symbol. */
3702 if (! TREE_ASM_WRITTEN (name_tree
))
3704 TREE_ASM_WRITTEN (name_tree
) = 1;
3705 fputs ("\t.extern\t", file
);
3706 assemble_name (file
, p
->name
);
3707 fprintf (file
, ", %d\n", p
->size
);
3711 fprintf (file
, "\n\t.text\n");
3712 rewind (asm_out_text_file
);
3713 if (ferror (asm_out_text_file
))
3714 fatal_io_error (temp_filename
);
3716 while ((len
= fread (buffer
, 1, sizeof (buffer
), asm_out_text_file
)) > 0)
3717 if (fwrite (buffer
, 1, len
, file
) != len
)
3718 pfatal_with_name (asm_file_name
);
3721 pfatal_with_name (temp_filename
);
3723 if (fclose (asm_out_text_file
) != 0)
3724 pfatal_with_name (temp_filename
);
3729 /* Emit either a label, .comm, or .lcomm directive, and mark
3730 that the symbol is used, so that we don't emit an .extern
3731 for it in mips_asm_file_end. */
3734 mips_declare_object (stream
, name
, init_string
, final_string
, size
)
3741 fputs (init_string
, stream
); /* "", "\t.comm\t", or "\t.lcomm\t" */
3742 assemble_name (stream
, name
);
3743 fprintf (stream
, final_string
, size
); /* ":\n", ",%u\n", ",%u\n" */
3745 if (TARGET_GP_OPT
&& mips_section_threshold
!= 0)
3747 tree name_tree
= get_identifier (name
);
3748 TREE_ASM_WRITTEN (name_tree
) = 1;
3753 /* Output a double precision value to the assembler. If both the
3754 host and target are IEEE, emit the values in hex. */
3757 mips_output_double (stream
, value
)
3759 REAL_VALUE_TYPE value
;
3761 #ifdef REAL_VALUE_TO_TARGET_DOUBLE
3763 REAL_VALUE_TO_TARGET_DOUBLE (value
, value_long
);
3765 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n",
3766 value_long
[0], value
, value_long
[1]);
3768 fprintf (stream
, "\t.double\t%.20g\n", value
);
3773 /* Output a single precision value to the assembler. If both the
3774 host and target are IEEE, emit the values in hex. */
3777 mips_output_float (stream
, value
)
3779 REAL_VALUE_TYPE value
;
3781 #ifdef REAL_VALUE_TO_TARGET_SINGLE
3783 REAL_VALUE_TO_TARGET_SINGLE (value
, value_long
);
3785 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long
, value
);
3787 fprintf (stream
, "\t.float\t%.12g\n", value
);
3792 /* Return TRUE if any register used in the epilogue is used. This to insure
3793 any insn put into the epilogue delay slots is safe. */
3796 epilogue_reg_mentioned_p (insn
)
3801 register enum rtx_code code
;
3807 if (GET_CODE (insn
) == LABEL_REF
)
3810 code
= GET_CODE (insn
);
3814 regno
= REGNO (insn
);
3815 if (regno
== STACK_POINTER_REGNUM
)
3818 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
3821 if (!call_used_regs
[regno
])
3824 if (regno
!= MIPS_TEMP1_REGNUM
&& regno
!= MIPS_TEMP2_REGNUM
)
3827 if (!current_frame_info
.initialized
)
3828 compute_frame_size (get_frame_size ());
3830 return (current_frame_info
.total_size
>= 32768);
3840 fmt
= GET_RTX_FORMAT (code
);
3841 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3846 for (j
= XVECLEN (insn
, i
) - 1; j
>= 0; j
--)
3847 if (epilogue_reg_mentioned_p (XVECEXP (insn
, i
, j
)))
3850 else if (fmt
[i
] == 'e' && epilogue_reg_mentioned_p (XEXP (insn
, i
)))
3858 /* Return the bytes needed to compute the frame pointer from the current
3861 Mips stack frames look like:
3863 Before call After call
3864 +-----------------------+ +-----------------------+
3867 | caller's temps. | | caller's temps. |
3869 +-----------------------+ +-----------------------+
3871 | arguments on stack. | | arguments on stack. |
3873 +-----------------------+ +-----------------------+
3874 | 4 words to save | | 4 words to save |
3875 | arguments passed | | arguments passed |
3876 | in registers, even | | in registers, even |
3877 SP->| if not passed. | FP->| if not passed. |
3878 +-----------------------+ +-----------------------+
3880 | GP save for V.4 abi |
3882 +-----------------------+
3884 | fp register save |
3886 +-----------------------+
3888 | gp register save |
3890 +-----------------------+
3894 +-----------------------+
3896 | alloca allocations |
3898 +-----------------------+
3900 | arguments on stack |
3902 +-----------------------+
3904 | arguments passed |
3905 | in registers, even |
3906 low SP->| if not passed. |
3907 memory +-----------------------+
3912 compute_frame_size (size
)
3913 int size
; /* # of var. bytes allocated */
3916 long total_size
; /* # bytes that the entire frame takes up */
3917 long var_size
; /* # bytes that variables take up */
3918 long args_size
; /* # bytes that outgoing arguments take up */
3919 long extra_size
; /* # extra bytes */
3920 long gp_reg_rounded
; /* # bytes needed to store gp after rounding */
3921 long gp_reg_size
; /* # bytes needed to store gp regs */
3922 long fp_reg_size
; /* # bytes needed to store fp regs */
3923 long mask
; /* mask of saved gp registers */
3924 long fmask
; /* mask of saved fp registers */
3925 int fp_inc
; /* 1 or 2 depending on the size of fp regs */
3926 long fp_bits
; /* bitmask to use for each fp register */
3932 extra_size
= MIPS_STACK_ALIGN (((TARGET_ABICALLS
) ? UNITS_PER_WORD
: 0));
3933 var_size
= MIPS_STACK_ALIGN (size
);
3934 args_size
= MIPS_STACK_ALIGN (current_function_outgoing_args_size
);
3936 /* The MIPS 3.0 linker does not like functions that dynamically
3937 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
3938 looks like we are trying to create a second frame pointer to the
3939 function, so allocate some stack space to make it happy. */
3941 if (args_size
== 0 && current_function_calls_alloca
)
3942 args_size
= 4*UNITS_PER_WORD
;
3944 total_size
= var_size
+ args_size
+ extra_size
;
3946 /* Calculate space needed for gp registers. */
3947 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
3949 if (MUST_SAVE_REGISTER (regno
))
3951 gp_reg_size
+= UNITS_PER_WORD
;
3952 mask
|= 1L << (regno
- GP_REG_FIRST
);
3956 /* Calculate space needed for fp registers. */
3968 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
+= fp_inc
)
3970 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
3972 fp_reg_size
+= 2*UNITS_PER_WORD
;
3973 fmask
|= fp_bits
<< (regno
- FP_REG_FIRST
);
3977 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
3978 total_size
+= gp_reg_rounded
+ fp_reg_size
;
3980 if (total_size
== extra_size
)
3981 total_size
= extra_size
= 0;
3983 /* Save other computed information. */
3984 current_frame_info
.total_size
= total_size
;
3985 current_frame_info
.var_size
= var_size
;
3986 current_frame_info
.args_size
= args_size
;
3987 current_frame_info
.extra_size
= extra_size
;
3988 current_frame_info
.gp_reg_size
= gp_reg_size
;
3989 current_frame_info
.fp_reg_size
= fp_reg_size
;
3990 current_frame_info
.mask
= mask
;
3991 current_frame_info
.fmask
= fmask
;
3992 current_frame_info
.initialized
= reload_completed
;
3993 current_frame_info
.num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
3994 current_frame_info
.num_fp
= fp_reg_size
/ (2*UNITS_PER_WORD
);
3998 unsigned long offset
= args_size
+ var_size
+ gp_reg_size
- UNITS_PER_WORD
;
3999 current_frame_info
.gp_sp_offset
= offset
;
4000 current_frame_info
.gp_save_offset
= offset
- total_size
;
4004 current_frame_info
.gp_sp_offset
= 0;
4005 current_frame_info
.gp_save_offset
= 0;
4011 unsigned long offset
= args_size
+ var_size
+ gp_reg_rounded
+ fp_reg_size
- 2*UNITS_PER_WORD
;
4012 current_frame_info
.fp_sp_offset
= offset
;
4013 current_frame_info
.fp_save_offset
= offset
- total_size
+ UNITS_PER_WORD
;
4017 current_frame_info
.fp_sp_offset
= 0;
4018 current_frame_info
.fp_save_offset
= 0;
4021 /* Ok, we're done. */
4026 /* Common code to emit the insns (or to write the instructions to a file)
4027 to save/restore registers.
4029 Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg)
4030 is not modified within save_restore_insns. */
4032 #define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0)
4035 save_restore_insns (store_p
, large_reg
, large_offset
, file
)
4036 int store_p
; /* true if this is prologue */
4037 rtx large_reg
; /* register holding large offset constant or NULL */
4038 long large_offset
; /* large constant offset value */
4039 FILE *file
; /* file to write instructions to instead of making RTL */
4041 long mask
= current_frame_info
.mask
;
4042 long fmask
= current_frame_info
.fmask
;
4050 if (frame_pointer_needed
&& !BITSET_P (mask
, FRAME_POINTER_REGNUM
- GP_REG_FIRST
))
4053 if (mask
== 0 && fmask
== 0)
4056 /* Save registers starting from high to low. The debuggers prefer
4057 at least the return register be stored at func+4, and also it
4058 allows us not to need a nop in the epilog if at least one
4059 register is reloaded in addition to return address. */
4061 /* Save GP registers if needed. */
4064 /* Pick which pointer to use as a base register. For small
4065 frames, just use the stack pointer. Otherwise, use a
4066 temporary register. Save 2 cycles if the save area is near
4067 the end of a large frame, by reusing the constant created in
4068 the prologue/epilogue to adjust the stack frame. */
4070 gp_offset
= current_frame_info
.gp_sp_offset
;
4071 end_offset
= gp_offset
- (current_frame_info
.gp_reg_size
- UNITS_PER_WORD
);
4073 if (gp_offset
< 0 || end_offset
< 0)
4074 fatal ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
4075 gp_offset
, end_offset
);
4077 else if (gp_offset
< 32768)
4079 base_reg_rtx
= stack_pointer_rtx
;
4083 else if (large_reg
!= (rtx
)0
4084 && (((unsigned long)(large_offset
- gp_offset
)) < 32768)
4085 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4087 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4088 base_offset
= large_offset
;
4089 if (file
== (FILE *)0)
4090 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4092 fprintf (file
, "\taddu\t%s,%s,%s\n",
4093 reg_names
[MIPS_TEMP2_REGNUM
],
4094 reg_names
[REGNO (large_reg
)],
4095 reg_names
[STACK_POINTER_REGNUM
]);
4100 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4101 base_offset
= gp_offset
;
4102 if (file
== (FILE *)0)
4104 emit_move_insn (base_reg_rtx
, GEN_INT (gp_offset
));
4105 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4108 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n",
4109 reg_names
[MIPS_TEMP2_REGNUM
],
4112 reg_names
[MIPS_TEMP2_REGNUM
],
4113 reg_names
[MIPS_TEMP2_REGNUM
],
4114 reg_names
[STACK_POINTER_REGNUM
]);
4117 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
4119 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
4121 if (file
== (FILE *)0)
4123 rtx reg_rtx
= gen_rtx (REG
, Pmode
, regno
);
4124 rtx mem_rtx
= gen_rtx (MEM
, Pmode
,
4125 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4126 GEN_INT (gp_offset
- base_offset
)));
4129 emit_move_insn (mem_rtx
, reg_rtx
);
4131 emit_move_insn (reg_rtx
, mem_rtx
);
4134 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4135 (store_p
) ? "sw" : "lw",
4137 gp_offset
- base_offset
,
4138 reg_names
[REGNO(base_reg_rtx
)]);
4140 gp_offset
-= UNITS_PER_WORD
;
4146 base_reg_rtx
= (rtx
)0; /* Make sure these are initialzed */
4150 /* Save floating point registers if needed. */
4153 int fp_inc
= (TARGET_FLOAT64
) ? 1 : 2;
4155 /* Pick which pointer to use as a base register. */
4156 fp_offset
= current_frame_info
.fp_sp_offset
;
4157 end_offset
= fp_offset
- (current_frame_info
.fp_reg_size
- 2*UNITS_PER_WORD
);
4159 if (fp_offset
< 0 || end_offset
< 0)
4160 fatal ("fp_offset (%ld) or end_offset (%ld) is less than zero.",
4161 fp_offset
, end_offset
);
4163 else if (fp_offset
< 32768)
4165 base_reg_rtx
= stack_pointer_rtx
;
4169 else if (base_reg_rtx
!= (rtx
)0
4170 && (((unsigned long)(base_offset
- fp_offset
)) < 32768)
4171 && (((unsigned long)(base_offset
- end_offset
)) < 32768))
4173 ; /* already set up for gp registers above */
4176 else if (large_reg
!= (rtx
)0
4177 && (((unsigned long)(large_offset
- fp_offset
)) < 32768)
4178 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4180 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4181 base_offset
= large_offset
;
4182 if (file
== (FILE *)0)
4183 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4185 fprintf (file
, "\taddu\t%s,%s,%s\n",
4186 reg_names
[MIPS_TEMP2_REGNUM
],
4187 reg_names
[REGNO (large_reg
)],
4188 reg_names
[STACK_POINTER_REGNUM
]);
4193 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4194 base_offset
= fp_offset
;
4195 if (file
== (FILE *)0)
4197 emit_move_insn (base_reg_rtx
, GEN_INT (fp_offset
));
4198 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4201 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n",
4202 reg_names
[MIPS_TEMP2_REGNUM
],
4205 reg_names
[MIPS_TEMP2_REGNUM
],
4206 reg_names
[MIPS_TEMP2_REGNUM
],
4207 reg_names
[STACK_POINTER_REGNUM
]);
4210 for (regno
= FP_REG_LAST
-1; regno
>= FP_REG_FIRST
; regno
-= fp_inc
)
4212 if (BITSET_P (fmask
, regno
- FP_REG_FIRST
))
4214 if (file
== (FILE *)0)
4216 rtx reg_rtx
= gen_rtx (REG
, DFmode
, regno
);
4217 rtx mem_rtx
= gen_rtx (MEM
, DFmode
,
4218 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4219 GEN_INT (fp_offset
- base_offset
)));
4222 emit_move_insn (mem_rtx
, reg_rtx
);
4224 emit_move_insn (reg_rtx
, mem_rtx
);
4227 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4228 (store_p
) ? "s.d" : "l.d",
4230 fp_offset
- base_offset
,
4231 reg_names
[REGNO(base_reg_rtx
)]);
4234 fp_offset
-= 2*UNITS_PER_WORD
;
4241 /* Set up the stack and frame (if desired) for the function. */
4244 function_prologue (file
, size
)
4248 long tsize
= current_frame_info
.total_size
;
4250 ASM_OUTPUT_SOURCE_FILENAME (file
, DECL_SOURCE_FILE (current_function_decl
));
4252 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
4253 ASM_OUTPUT_SOURCE_LINE (file
, DECL_SOURCE_LINE (current_function_decl
));
4255 inside_function
= 1;
4256 fputs ("\t.ent\t", file
);
4257 assemble_name (file
, current_function_name
);
4260 assemble_name (file
, current_function_name
);
4261 fputs (":\n", file
);
4263 if (TARGET_ABICALLS
)
4265 "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
4266 reg_names
[ GP_REG_FIRST
+ 25 ]);
4268 tsize
= current_frame_info
.total_size
;
4269 if (tsize
> 0 && TARGET_ABICALLS
)
4270 fprintf (file
, "\t.cprestore %d\n", tsize
+ STARTING_FRAME_OFFSET
);
4272 fprintf (file
, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args = %d, extra= %d\n",
4273 reg_names
[ (frame_pointer_needed
) ? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
],
4275 reg_names
[31 + GP_REG_FIRST
],
4276 current_frame_info
.var_size
,
4277 current_frame_info
.num_gp
,
4278 current_frame_info
.num_fp
,
4279 current_function_outgoing_args_size
,
4280 current_frame_info
.extra_size
);
4282 fprintf (file
, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n",
4283 current_frame_info
.mask
,
4284 current_frame_info
.gp_save_offset
,
4285 current_frame_info
.fmask
,
4286 current_frame_info
.fp_save_offset
);
4290 /* Expand the prologue into a bunch of separate insns. */
4293 mips_expand_prologue ()
4297 rtx tmp_rtx
= (rtx
)0;
4298 char *arg_name
= (char *)0;
4299 tree fndecl
= current_function_decl
;
4300 tree fntype
= TREE_TYPE (fndecl
);
4301 tree fnargs
= (TREE_CODE (fntype
) != METHOD_TYPE
)
4302 ? DECL_ARGUMENTS (fndecl
)
4308 CUMULATIVE_ARGS args_so_far
;
4310 /* Determine the last argument, and get its name. */
4312 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, (rtx
)0);
4313 regno
= GP_ARG_FIRST
;
4315 for (cur_arg
= fnargs
; cur_arg
!= (tree
)0; cur_arg
= next_arg
)
4317 tree type
= DECL_ARG_TYPE (cur_arg
);
4318 enum machine_mode passed_mode
= TYPE_MODE (type
);
4319 rtx entry_parm
= FUNCTION_ARG (args_so_far
,
4321 DECL_ARG_TYPE (cur_arg
),
4328 /* passed in a register, so will get homed automatically */
4329 if (GET_MODE (entry_parm
) == BLKmode
)
4330 words
= (int_size_in_bytes (type
) + 3) / 4;
4332 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
4334 regno
= REGNO (entry_parm
) + words
- 1;
4338 regno
= GP_ARG_LAST
+1;
4342 FUNCTION_ARG_ADVANCE (args_so_far
,
4344 DECL_ARG_TYPE (cur_arg
),
4347 next_arg
= TREE_CHAIN (cur_arg
);
4348 if (next_arg
== (tree
)0)
4350 if (DECL_NAME (cur_arg
))
4351 arg_name
= IDENTIFIER_POINTER (DECL_NAME (cur_arg
));
4357 /* In order to pass small structures by value in registers
4358 compatibly with the MIPS compiler, we need to shift the value
4359 into the high part of the register. Function_arg has encoded a
4360 PARALLEL rtx, holding a vector of adjustments to be made as the
4361 next_arg_reg variable, so we split up the insns, and emit them
4364 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
4365 if (next_arg_reg
!= (rtx
)0 && GET_CODE (next_arg_reg
) == PARALLEL
)
4367 rtvec adjust
= XVEC (next_arg_reg
, 0);
4368 int num
= GET_NUM_ELEM (adjust
);
4370 for (i
= 0; i
< num
; i
++)
4372 rtx pattern
= RTVEC_ELT (adjust
, i
);
4373 if (GET_CODE (pattern
) != SET
4374 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
4375 abort_with_insn (pattern
, "Insn is not a shift");
4377 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
4378 emit_insn (pattern
);
4382 /* If this function is a varargs function, store any registers that
4383 would normally hold arguments ($4 - $7) on the stack. */
4384 if ((TYPE_ARG_TYPES (fntype
) != 0
4385 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
))) != void_type_node
))
4386 || (arg_name
!= (char *)0
4387 && ((arg_name
[0] == '_' && strcmp (arg_name
, "__builtin_va_alist") == 0)
4388 || (arg_name
[0] == 'v' && strcmp (arg_name
, "va_alist") == 0))))
4390 for (; regno
<= GP_ARG_LAST
; regno
++)
4392 rtx ptr
= stack_pointer_rtx
;
4393 if (regno
!= GP_ARG_FIRST
)
4394 ptr
= gen_rtx (PLUS
, Pmode
, ptr
,
4395 GEN_INT ((regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
));
4397 emit_move_insn (gen_rtx (MEM
, Pmode
, ptr
), gen_rtx (REG
, Pmode
, regno
));
4401 tsize
= compute_frame_size (get_frame_size ());
4404 rtx tsize_rtx
= GEN_INT (tsize
);
4408 tmp_rtx
= gen_rtx (REG
, SImode
, MIPS_TEMP1_REGNUM
);
4409 emit_move_insn (tmp_rtx
, tsize_rtx
);
4410 tsize_rtx
= tmp_rtx
;
4413 emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
, tsize_rtx
));
4415 save_restore_insns (TRUE
, tmp_rtx
, tsize
, (FILE *)0);
4417 if (frame_pointer_needed
)
4418 emit_insn (gen_movsi (frame_pointer_rtx
, stack_pointer_rtx
));
4421 /* If we are profiling, make sure no instructions are scheduled before
4422 the call to mcount. */
4424 if (profile_flag
|| profile_block_flag
)
4425 emit_insn (gen_blockage ());
4429 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */
4431 #define RA_MASK ((long) 0x80000000) /* 1 << 31 */
4434 function_epilogue (file
, size
)
4439 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4440 char *t1_str
= reg_names
[MIPS_TEMP1_REGNUM
];
4441 rtx epilogue_delay
= current_function_epilogue_delay_list
;
4442 int noreorder
= !TARGET_MIPS_AS
|| (epilogue_delay
!= 0);
4443 int noepilogue
= FALSE
;
4444 int load_nop
= FALSE
;
4446 rtx tmp_rtx
= (rtx
)0;
4450 /* The epilogue does not depend on any registers, but the stack
4451 registers, so we assume that if we have 1 pending nop, it can be
4452 ignored, and 2 it must be filled (2 nops occur for integer
4453 multiply and divide). */
4455 if (dslots_number_nops
> 0)
4457 if (dslots_number_nops
== 1)
4459 dslots_number_nops
= 0;
4460 dslots_load_filled
++;
4464 while (--dslots_number_nops
> 0)
4465 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
4468 if (set_noreorder
> 0 && --set_noreorder
== 0)
4469 fputs ("\t.set\treorder\n", file
);
4475 fputs ("\t.set\tat\n", file
);
4476 error ("internal gcc error: .set noat left on in epilogue");
4479 if (set_nomacro
!= 0)
4482 fputs ("\t.set\tmacro\n", file
);
4483 error ("internal gcc error: .set nomacro left on in epilogue");
4486 if (set_noreorder
!= 0)
4489 fputs ("\t.set\treorder\n", file
);
4490 error ("internal gcc error: .set noreorder left on in epilogue");
4493 if (set_volatile
!= 0)
4496 fprintf (file
, "\t#.set\tnovolatile\n", (TARGET_MIPS_AS
) ? "" : "#");
4497 error ("internal gcc error: .set volatile left on in epilogue");
4500 size
= MIPS_STACK_ALIGN (size
);
4501 tsize
= (!current_frame_info
.initialized
)
4502 ? compute_frame_size (size
)
4503 : current_frame_info
.total_size
;
4505 if (tsize
== 0 && epilogue_delay
== 0)
4507 rtx insn
= get_last_insn ();
4509 /* If the last insn was a BARRIER, we don't have to write any code
4510 because a jump (aka return) was put there. */
4511 if (GET_CODE (insn
) == NOTE
)
4512 insn
= prev_nonnote_insn (insn
);
4513 if (insn
&& GET_CODE (insn
) == BARRIER
)
4521 /* In the reload sequence, we don't need to fill the load delay
4522 slots for most of the loads, also see if we can fill the final
4523 delay slot if not otherwise filled by the reload sequence. */
4526 fprintf (file
, "\t.set\tnoreorder\n");
4530 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str
, (long)tsize
, (long)tsize
);
4531 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
4534 if (frame_pointer_needed
)
4535 fprintf (file
, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
4536 sp_str
, reg_names
[FRAME_POINTER_REGNUM
]);
4538 save_restore_insns (FALSE
, tmp_rtx
, tsize
, file
);
4540 load_only_r31
= (current_frame_info
.mask
== RA_MASK
4541 && current_frame_info
.fmask
== 0);
4545 /* If the only register saved is the return address, we need a
4546 nop, unless we have an instruction to put into it. Otherwise
4547 we don't since reloading multiple registers doesn't reference
4548 the register being loaded. */
4553 final_scan_insn (XEXP (epilogue_delay
, 0),
4557 1); /* nopeepholes */
4560 fprintf (file
, "\tnop\n");
4565 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
4568 fprintf (file
, "\taddu\t%s,%s,%s\n", sp_str
, sp_str
, t1_str
);
4571 fprintf (file
, "\taddu\t%s,%s,%d\n", sp_str
, sp_str
, tsize
);
4573 else if (!load_only_r31
&& epilogue_delay
!= 0)
4574 final_scan_insn (XEXP (epilogue_delay
, 0),
4578 1); /* nopeepholes */
4580 fprintf (file
, "\t.set\treorder\n");
4586 fprintf (file
, "\taddu\t%s,%s,%s\n", sp_str
, sp_str
, t1_str
);
4589 fprintf (file
, "\taddu\t%s,%s,%d\n", sp_str
, sp_str
, tsize
);
4591 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
4595 fputs ("\t.end\t", file
);
4596 assemble_name (file
, current_function_name
);
4601 int num_gp_regs
= current_frame_info
.gp_reg_size
/ 4;
4602 int num_fp_regs
= current_frame_info
.fp_reg_size
/ 8;
4603 int num_regs
= num_gp_regs
+ num_fp_regs
;
4604 char *name
= current_function_name
;
4609 dslots_load_total
+= num_regs
;
4612 dslots_jump_total
++;
4616 dslots_load_filled
+= num_regs
;
4618 /* If the only register saved is the return register, we
4619 can't fill this register's delay slot. */
4621 if (load_only_r31
&& epilogue_delay
== 0)
4622 dslots_load_filled
--;
4624 if (tsize
> 0 || (!load_only_r31
&& epilogue_delay
!= 0))
4625 dslots_jump_filled
++;
4629 "%-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",
4631 (frame_pointer_needed
) ? 'y' : 'n',
4632 ((current_frame_info
.mask
& RA_MASK
) != 0) ? 'n' : 'y',
4633 (current_function_calls_alloca
) ? 'y' : 'n',
4634 (current_function_calls_setjmp
) ? 'y' : 'n',
4635 (long)current_frame_info
.total_size
,
4636 (long)current_function_outgoing_args_size
,
4637 num_gp_regs
, num_fp_regs
,
4638 dslots_load_total
, dslots_load_filled
,
4639 dslots_jump_total
, dslots_jump_filled
,
4640 num_refs
[0], num_refs
[1], num_refs
[2]);
4642 if (HALF_PIC_NUMBER_PTRS
> prev_half_pic_ptrs
)
4644 fprintf (stderr
, " half-pic=%3d", HALF_PIC_NUMBER_PTRS
- prev_half_pic_ptrs
);
4645 prev_half_pic_ptrs
= HALF_PIC_NUMBER_PTRS
;
4648 if (HALF_PIC_NUMBER_REFS
> prev_half_pic_refs
)
4650 fprintf (stderr
, " pic-ref=%3d", HALF_PIC_NUMBER_REFS
- prev_half_pic_refs
);
4651 prev_half_pic_refs
= HALF_PIC_NUMBER_REFS
;
4654 fputc ('\n', stderr
);
4657 /* Reset state info for each function. */
4658 inside_function
= FALSE
;
4659 ignore_line_number
= FALSE
;
4660 dslots_load_total
= 0;
4661 dslots_jump_total
= 0;
4662 dslots_load_filled
= 0;
4663 dslots_jump_filled
= 0;
4667 mips_load_reg
= (rtx
)0;
4668 mips_load_reg2
= (rtx
)0;
4669 current_frame_info
= zero_frame_info
;
4671 /* Restore the output file if optimizing the GP (optimizing the GP causes
4672 the text to be diverted to a tempfile, so that data decls come before
4673 references to the data). */
4676 asm_out_file
= asm_out_data_file
;
4680 /* Expand the epilogue into a bunch of separate insns. */
4683 mips_expand_epilogue ()
4685 long tsize
= current_frame_info
.total_size
;
4686 rtx tsize_rtx
= GEN_INT (tsize
);
4687 rtx tmp_rtx
= (rtx
)0;
4691 tmp_rtx
= gen_rtx (REG
, SImode
, MIPS_TEMP1_REGNUM
);
4692 emit_move_insn (tmp_rtx
, tsize_rtx
);
4693 tsize_rtx
= tmp_rtx
;
4698 if (frame_pointer_needed
)
4699 emit_insn (gen_movsi (stack_pointer_rtx
, frame_pointer_rtx
));
4701 save_restore_insns (FALSE
, tmp_rtx
, tsize
, (FILE *)0);
4703 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
, tsize_rtx
));
4706 emit_jump_insn (gen_return_internal (gen_rtx (REG
, Pmode
, GP_REG_FIRST
+31)));
4710 /* Define the number of delay slots needed for the function epilogue.
4712 On the mips, we need a slot if either no stack has been allocated,
4713 or the only register saved is the return register. */
4716 mips_epilogue_delay_slots ()
4718 if (!current_frame_info
.initialized
)
4719 (void) compute_frame_size (get_frame_size ());
4721 if (current_frame_info
.total_size
== 0)
4724 if (current_frame_info
.mask
== RA_MASK
&& current_frame_info
.fmask
== 0)
4731 /* Return true if this function is known to have a null epilogue.
4732 This allows the optimizer to omit jumps to jumps if no stack
4736 simple_epilogue_p ()
4738 if (!reload_completed
)
4741 if (current_frame_info
.initialized
)
4742 return current_frame_info
.total_size
== 0;
4744 return (compute_frame_size (get_frame_size ())) == 0;