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 /* Generating calls to position independent functions? */
194 enum mips_abicalls_type mips_abicalls
;
196 /* Array to RTX class classification. At present, we care about
197 whether the operator is an add-type operator, or a divide/modulus,
198 and if divide/modulus, whether it is unsigned. This is for the
200 char mips_rtx_classify
[NUM_RTX_CODE
];
202 /* Array giving truth value on whether or not a given hard register
203 can support a given mode. */
204 char mips_hard_regno_mode_ok
[(int)MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
206 /* Current frame information calculated by compute_frame_size. */
207 struct mips_frame_info current_frame_info
;
209 /* Zero structure to initialize current_frame_info. */
210 struct mips_frame_info zero_frame_info
;
212 /* Temporary filename used to buffer .text until end of program
214 static char *temp_filename
;
216 /* List of all MIPS punctuation characters used by print_operand. */
217 char mips_print_operand_punct
[256];
219 /* Map GCC register number to debugger register number. */
220 int mips_dbx_regno
[FIRST_PSEUDO_REGISTER
];
222 /* Buffer to use to enclose a load/store operation with %{ %} to
223 turn on .set volatile. */
224 static char volatile_buffer
[60];
226 /* Hardware names for the registers. If -mrnames is used, this
227 will be overwritten with mips_sw_reg_names. */
229 char mips_reg_names
[][8] =
231 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
232 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
233 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
234 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
235 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
236 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
237 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
238 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
242 /* Mips software names for the registers, used to overwrite the
243 mips_reg_names array. */
245 char mips_sw_reg_names
[][8] =
247 "$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
248 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
249 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
250 "t8", "t9", "k0", "k1", "gp", "sp", "$fp", "ra",
251 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
252 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
253 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
254 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
258 /* Map hard register number to register class */
259 enum reg_class mips_regno_to_class
[] =
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 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
267 GR_REGS
, GR_REGS
, GR_REGS
, GR_REGS
,
268 GR_REGS
, GR_REGS
, GR_REGS
, GR_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 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
275 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
276 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
277 HI_REG
, LO_REG
, ST_REGS
280 /* Map register constraint character to register class. */
281 enum reg_class mips_char_to_class
[256] =
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
,
344 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
345 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
346 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
350 /* Return truth value of whether OP can be used as an operands
351 where a register or 16 bit unsigned integer is needed. */
354 uns_arith_operand (op
, mode
)
356 enum machine_mode mode
;
358 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT_UNSIGNED (op
))
361 return register_operand (op
, mode
);
364 /* Return truth value of whether OP can be used as an operands
365 where a 16 bit integer is needed */
368 arith_operand (op
, mode
)
370 enum machine_mode mode
;
372 if (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
))
375 return register_operand (op
, mode
);
378 /* Return truth value of whether OP can be used as an operand in a two
379 address arithmetic insn (such as set 123456,%o4) of mode MODE. */
382 arith32_operand (op
, mode
)
384 enum machine_mode mode
;
386 if (GET_CODE (op
) == CONST_INT
)
389 return register_operand (op
, mode
);
392 /* Return truth value of whether OP is a integer which fits in 16 bits */
397 enum machine_mode mode
;
399 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
402 /* Return truth value of whether OP is an integer which is too big to
403 be loaded with one instruction. */
408 enum machine_mode mode
;
412 if (GET_CODE (op
) != CONST_INT
)
416 if ((value
& ~0x0000ffff) == 0) /* ior reg,$r0,value */
419 if (((unsigned long)(value
+ 32768)) <= 32767) /* subu reg,$r0,value */
422 if ((value
& 0xffff0000) == value
) /* lui reg,value>>16 */
428 /* Return truth value of whether OP is a register or the constant 0. */
431 reg_or_0_operand (op
, mode
)
433 enum machine_mode mode
;
435 switch (GET_CODE (op
))
441 return (INTVAL (op
) == 0);
444 if (CONST_DOUBLE_HIGH (op
) != 0 || CONST_DOUBLE_LOW (op
) != 0)
451 return register_operand (op
, mode
);
457 /* Return truth value of whether OP is one of the special multiply/divide
458 registers (hi, lo). */
461 md_register_operand (op
, mode
)
463 enum machine_mode mode
;
465 return (GET_MODE_CLASS (mode
) == MODE_INT
466 && GET_CODE (op
) == REG
467 && MD_REG_P (REGNO (op
)));
470 /* Return truth value of whether OP is the FP status register. */
473 fpsw_register_operand (op
, mode
)
475 enum machine_mode mode
;
477 return (GET_CODE (op
) == REG
&& ST_REG_P (REGNO (op
)));
480 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
483 mips_const_double_ok (op
, mode
)
485 enum machine_mode mode
;
487 if (GET_CODE (op
) != CONST_DOUBLE
)
493 if (mode
!= SFmode
&& mode
!= DFmode
)
496 if (CONST_DOUBLE_HIGH (op
) == 0 && CONST_DOUBLE_LOW (op
) == 0)
499 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
500 if (TARGET_MIPS_AS
) /* gas doesn't like li.d/li.s yet */
502 union { double d
; int i
[2]; } u
;
505 u
.i
[0] = CONST_DOUBLE_LOW (op
);
506 u
.i
[1] = CONST_DOUBLE_HIGH (op
);
510 return FALSE
; /* NAN */
515 /* Rather than trying to get the accuracy down to the last bit,
516 just use approximate ranges. */
518 if (mode
== DFmode
&& d
> 1.0e-300 && d
< 1.0e300
)
521 if (mode
== SFmode
&& d
> 1.0e-38 && d
< 1.0e+38)
529 /* Return truth value if a memory operand fits in a single instruction
530 (ie, register + small offset). */
533 simple_memory_operand (op
, mode
)
535 enum machine_mode mode
;
537 rtx addr
, plus0
, plus1
;
539 /* Eliminate non-memory operations */
540 if (GET_CODE (op
) != MEM
)
543 /* dword operations really put out 2 instructions, so eliminate them. */
544 if (GET_MODE_SIZE (GET_MODE (op
)) > (HAVE_64BIT_P () ? 8 : 4))
547 /* Decode the address now. */
549 switch (GET_CODE (addr
))
558 return SMALL_INT (op
);
561 plus0
= XEXP (addr
, 0);
562 plus1
= XEXP (addr
, 1);
563 if (GET_CODE (plus0
) == REG
564 && GET_CODE (plus1
) == CONST_INT
565 && SMALL_INT (plus1
))
568 else if (GET_CODE (plus1
) == REG
569 && GET_CODE (plus0
) == CONST_INT
570 && SMALL_INT (plus0
))
577 /* We used to allow small symbol refs here (ie, stuff in .sdata
578 or .sbss), but this causes some bugs in G++. Also, it won't
579 interfere if the MIPS linker rewrites the store instruction
580 because the function is PIC. */
582 case LABEL_REF
: /* never gp relative */
586 /* If -G 0, we can never have a GP relative memory operation.
587 Also, save some time if not optimizing. */
588 if (mips_section_threshold
== 0 || !optimize
|| !TARGET_GP_OPT
)
592 rtx offset
= const0_rtx
;
593 addr
= eliminate_constant_term (addr
, &offset
);
594 if (GET_CODE (op
) != SYMBOL_REF
)
597 /* let's be paranoid.... */
598 if (INTVAL (offset
) < 0 || INTVAL (offset
) > 0xffff)
604 return SYMBOL_REF_FLAG (addr
);
611 /* Return true if the code of this rtx pattern is EQ or NE. */
614 equality_op (op
, mode
)
616 enum machine_mode mode
;
618 if (mode
!= GET_MODE (op
))
621 return (classify_op (op
, mode
) & CLASS_EQUALITY_OP
) != 0;
624 /* Return true if the code is a relational operations (EQ, LE, etc.) */
629 enum machine_mode mode
;
631 if (mode
!= GET_MODE (op
))
634 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
638 /* Genrecog does not take the type of match_operator into consideration,
639 and would complain about two patterns being the same if the same
640 function is used, so make it believe they are different. */
645 enum machine_mode mode
;
647 if (mode
!= GET_MODE (op
))
650 return (classify_op (op
, mode
) & CLASS_CMP_OP
) != 0;
653 /* Return true if the code is an unsigned relational operations (LEU, etc.) */
658 enum machine_mode mode
;
660 if (mode
!= GET_MODE (op
))
663 return (classify_op (op
, mode
) & CLASS_UNS_CMP_OP
) == CLASS_UNS_CMP_OP
;
666 /* Return true if the code is a relational operation FP can use. */
671 enum machine_mode mode
;
673 if (mode
!= GET_MODE (op
))
676 return (classify_op (op
, mode
) & CLASS_FCMP_OP
) != 0;
680 /* Return true if the operand is either the PC or a label_ref. */
683 pc_or_label_operand (op
, mode
)
685 enum machine_mode mode
;
690 if (GET_CODE (op
) == LABEL_REF
)
696 /* Test for a valid operand for a call instruction.
697 Don't allow the arg pointer register or virtual regs
698 since they may change into reg + const, which the patterns
702 call_insn_operand (op
, mode
)
704 enum machine_mode mode
;
706 if (GET_CODE (op
) == MEM
707 && (CONSTANT_ADDRESS_P (XEXP (op
, 0))
708 || (GET_CODE (XEXP (op
, 0)) == REG
709 && XEXP (op
, 0) != arg_pointer_rtx
710 && !(REGNO (XEXP (op
, 0)) >= FIRST_PSEUDO_REGISTER
711 && REGNO (XEXP (op
, 0)) <= LAST_VIRTUAL_REGISTER
))))
716 /* Return an operand string if the given instruction's delay slot or
717 wrap it in a .set noreorder section. This is for filling delay
718 slots on load type instructions under GAS, which does no reordering
719 on its own. For the MIPS assembler, all we do is update the filled
720 delay slot statistics.
722 We assume that operands[0] is the target register that is set.
724 In order to check the next insn, most of this functionality is moved
725 to FINAL_PRESCAN_INSN, and we just set the global variables that
729 mips_fill_delay_slot (ret
, type
, operands
, cur_insn
)
730 char *ret
; /* normal string to return */
731 enum delay_type type
; /* type of delay */
732 rtx operands
[]; /* operands to use */
733 rtx cur_insn
; /* current insn */
735 register rtx set_reg
;
736 register enum machine_mode mode
;
737 register rtx next_insn
= (cur_insn
) ? NEXT_INSN (cur_insn
) : (rtx
)0;
738 register int num_nops
;
740 if (type
== DELAY_LOAD
|| type
== DELAY_FCMP
)
743 else if (type
== DELAY_HILO
)
749 /* Make sure that we don't put nop's after labels. */
750 next_insn
= NEXT_INSN (cur_insn
);
751 while (next_insn
!= (rtx
)0 && GET_CODE (next_insn
) == NOTE
)
752 next_insn
= NEXT_INSN (next_insn
);
754 dslots_load_total
+= num_nops
;
755 if (TARGET_DEBUG_F_MODE
757 || type
== DELAY_NONE
758 || operands
== (rtx
*)0
759 || cur_insn
== (rtx
)0
760 || next_insn
== (rtx
)0
761 || GET_CODE (next_insn
) == CODE_LABEL
762 || (set_reg
= operands
[0]) == (rtx
)0)
764 dslots_number_nops
= 0;
765 mips_load_reg
= (rtx
)0;
766 mips_load_reg2
= (rtx
)0;
767 mips_load_reg3
= (rtx
)0;
768 mips_load_reg4
= (rtx
)0;
772 set_reg
= operands
[0];
773 if (set_reg
== (rtx
)0)
776 while (GET_CODE (set_reg
) == SUBREG
)
777 set_reg
= SUBREG_REG (set_reg
);
779 mode
= GET_MODE (set_reg
);
780 dslots_number_nops
= num_nops
;
781 mips_load_reg
= set_reg
;
782 mips_load_reg2
= (mode
== DImode
|| mode
== DFmode
)
783 ? gen_rtx (REG
, SImode
, REGNO (set_reg
) + 1)
786 if (type
== DELAY_HILO
)
788 mips_load_reg3
= gen_rtx (REG
, SImode
, MD_REG_FIRST
);
789 mips_load_reg4
= gen_rtx (REG
, SImode
, MD_REG_FIRST
+1);
797 if (TARGET_GAS
&& set_noreorder
++ == 0)
798 fputs ("\t.set\tnoreorder\n", asm_out_file
);
804 /* Determine whether a memory reference takes one (based off of the GP pointer),
805 two (normal), or three (label + reg) instructions, and bump the appropriate
806 counter for -mstats. */
809 mips_count_memory_refs (op
, num
)
815 rtx addr
, plus0
, plus1
;
816 enum rtx_code code0
, code1
;
819 if (TARGET_DEBUG_B_MODE
)
821 fprintf (stderr
, "\n========== mips_count_memory_refs:\n");
825 /* Skip MEM if passed, otherwise handle movsi of address. */
826 addr
= (GET_CODE (op
) != MEM
) ? op
: XEXP (op
, 0);
828 /* Loop, going through the address RTL */
832 switch (GET_CODE (addr
))
842 plus0
= XEXP (addr
, 0);
843 plus1
= XEXP (addr
, 1);
844 code0
= GET_CODE (plus0
);
845 code1
= GET_CODE (plus1
);
855 if (code0
== CONST_INT
)
870 if (code1
== CONST_INT
)
877 if (code0
== SYMBOL_REF
|| code0
== LABEL_REF
|| code0
== CONST
)
884 if (code1
== SYMBOL_REF
|| code1
== LABEL_REF
|| code1
== CONST
)
894 n_words
= 2; /* always 2 words */
898 addr
= XEXP (addr
, 0);
903 n_words
= SYMBOL_REF_FLAG (addr
) ? 1 : 2;
912 n_words
+= additional
;
916 num_refs
[n_words
-1] += num
;
920 /* Return the appropriate instructions to move one operand to another. */
923 mips_move_1word (operands
, insn
, unsignedp
)
929 rtx op0
= operands
[0];
930 rtx op1
= operands
[1];
931 enum rtx_code code0
= GET_CODE (op0
);
932 enum rtx_code code1
= GET_CODE (op1
);
933 enum machine_mode mode
= GET_MODE (op0
);
934 int subreg_word0
= 0;
935 int subreg_word1
= 0;
936 enum delay_type delay
= DELAY_NONE
;
938 while (code0
== SUBREG
)
940 subreg_word0
+= SUBREG_WORD (op0
);
941 op0
= SUBREG_REG (op0
);
942 code0
= GET_CODE (op0
);
945 while (code1
== SUBREG
)
947 subreg_word1
+= SUBREG_WORD (op1
);
948 op1
= SUBREG_REG (op1
);
949 code1
= GET_CODE (op1
);
954 int regno0
= REGNO (op0
) + subreg_word0
;
958 int regno1
= REGNO (op1
) + subreg_word1
;
960 /* Just in case, don't do anything for assigning a register
961 to itself, unless we are filling a delay slot. */
962 if (regno0
== regno1
&& set_nomacro
== 0)
965 else if (GP_REG_P (regno0
))
967 if (GP_REG_P (regno1
))
970 else if (MD_REG_P (regno1
))
979 if (FP_REG_P (regno1
))
982 else if (regno1
== FPSW_REGNUM
)
983 ret
= "cfc1\t%0,$31";
987 else if (FP_REG_P (regno0
))
989 if (GP_REG_P (regno1
))
995 if (FP_REG_P (regno1
))
996 ret
= "mov.s\t%0,%1";
999 else if (MD_REG_P (regno0
))
1001 if (GP_REG_P (regno1
))
1008 else if (regno0
== FPSW_REGNUM
)
1010 if (GP_REG_P (regno1
))
1013 ret
= "ctc1\t%0,$31";
1018 else if (code1
== MEM
)
1023 mips_count_memory_refs (op1
, 1);
1025 if (GP_REG_P (regno0
))
1027 /* For loads, use the mode of the memory item, instead of the
1028 target, so zero/sign extend can use this code as well. */
1029 switch (GET_MODE (op1
))
1032 case SFmode
: ret
= "lw\t%0,%1"; break;
1033 case SImode
: ret
= "lw\t%0,%1"; break;
1034 case HImode
: ret
= (unsignedp
) ? "lhu\t%0,%1" : "lh\t%0,%1"; break;
1035 case QImode
: ret
= (unsignedp
) ? "lbu\t%0,%1" : "lb\t%0,%1"; break;
1039 else if (FP_REG_P (regno0
) && (mode
== SImode
|| mode
== SFmode
))
1042 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1044 int i
= strlen (ret
);
1045 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1048 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1049 ret
= volatile_buffer
;
1053 else if (code1
== CONST_INT
)
1055 if (INTVAL (op1
) == 0)
1057 if (GP_REG_P (regno0
))
1058 ret
= "move\t%0,%z1";
1060 else if (FP_REG_P (regno0
))
1063 ret
= "mtc1\t%z1,%0";
1067 else if (GP_REG_P (regno0
))
1068 ret
= (INTVAL (op1
) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1";
1071 else if (code1
== CONST_DOUBLE
&& mode
== SFmode
)
1073 if (CONST_DOUBLE_HIGH (op1
) == 0 && CONST_DOUBLE_LOW (op1
) == 0)
1075 if (GP_REG_P (regno0
))
1076 ret
= "move\t%0,%.";
1078 else if (FP_REG_P (regno0
))
1081 ret
= "mtc1\t%.,%0";
1088 ret
= "li.s\t%0,%1";
1092 else if (code1
== LABEL_REF
)
1095 mips_count_memory_refs (op1
, 1);
1100 else if (code1
== SYMBOL_REF
|| code1
== CONST
)
1102 if (HALF_PIC_P () && CONSTANT_P (op1
) && HALF_PIC_ADDRESS_P (op1
))
1104 rtx offset
= const0_rtx
;
1106 if (GET_CODE (op1
) == CONST
)
1107 op1
= eliminate_constant_term (XEXP (op1
, 0), &offset
);
1109 if (GET_CODE (op1
) == SYMBOL_REF
)
1111 operands
[2] = HALF_PIC_PTR (op1
);
1114 mips_count_memory_refs (operands
[2], 1);
1116 if (INTVAL (offset
) == 0)
1123 dslots_load_total
++;
1124 operands
[3] = offset
;
1125 ret
= (SMALL_INT (offset
))
1126 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"
1127 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1134 mips_count_memory_refs (op1
, 1);
1140 else if (code1
== PLUS
)
1142 rtx add_op0
= XEXP (op1
, 0);
1143 rtx add_op1
= XEXP (op1
, 1);
1145 if (GET_CODE (XEXP (op1
, 1)) == REG
&& GET_CODE (XEXP (op1
, 0)) == CONST_INT
)
1147 add_op0
= XEXP (op1
, 1); /* reverse operands */
1148 add_op1
= XEXP (op1
, 0);
1151 operands
[2] = add_op0
;
1152 operands
[3] = add_op1
;
1153 ret
= "add%:\t%0,%2,%3";
1157 else if (code0
== MEM
)
1160 mips_count_memory_refs (op0
, 1);
1164 int regno1
= REGNO (op1
) + subreg_word1
;
1166 if (GP_REG_P (regno1
))
1171 case SFmode
: ret
= "sw\t%1,%0"; break;
1172 case SImode
: ret
= "sw\t%1,%0"; break;
1173 case HImode
: ret
= "sh\t%1,%0"; break;
1174 case QImode
: ret
= "sb\t%1,%0"; break;
1178 else if (FP_REG_P (regno1
) && (mode
== SImode
|| mode
== SFmode
))
1182 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1187 case SFmode
: ret
= "sw\t%z1,%0"; break;
1188 case SImode
: ret
= "sw\t%z1,%0"; break;
1189 case HImode
: ret
= "sh\t%z1,%0"; break;
1190 case QImode
: ret
= "sb\t%z1,%0"; break;
1194 else if (code1
== CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op1
) == 0 && CONST_DOUBLE_LOW (op1
) == 0)
1199 case SFmode
: ret
= "sw\t%.,%0"; break;
1200 case SImode
: ret
= "sw\t%.,%0"; break;
1201 case HImode
: ret
= "sh\t%.,%0"; break;
1202 case QImode
: ret
= "sb\t%.,%0"; break;
1206 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1208 int i
= strlen (ret
);
1209 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1212 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1213 ret
= volatile_buffer
;
1217 if (ret
== (char *)0)
1219 abort_with_insn (insn
, "Bad move");
1223 if (delay
!= DELAY_NONE
)
1224 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1230 /* Return the appropriate instructions to move 2 words */
1233 mips_move_2words (operands
, insn
)
1238 rtx op0
= operands
[0];
1239 rtx op1
= operands
[1];
1240 enum rtx_code code0
= GET_CODE (operands
[0]);
1241 enum rtx_code code1
= GET_CODE (operands
[1]);
1242 int subreg_word0
= 0;
1243 int subreg_word1
= 0;
1244 enum delay_type delay
= DELAY_NONE
;
1246 while (code0
== SUBREG
)
1248 subreg_word0
+= SUBREG_WORD (op0
);
1249 op0
= SUBREG_REG (op0
);
1250 code0
= GET_CODE (op0
);
1253 while (code1
== SUBREG
)
1255 subreg_word1
+= SUBREG_WORD (op1
);
1256 op1
= SUBREG_REG (op1
);
1257 code1
= GET_CODE (op1
);
1262 int regno0
= REGNO (op0
) + subreg_word0
;
1266 int regno1
= REGNO (op1
) + subreg_word1
;
1268 /* Just in case, don't do anything for assigning a register
1269 to itself, unless we are filling a delay slot. */
1270 if (regno0
== regno1
&& set_nomacro
== 0)
1273 else if (FP_REG_P (regno0
))
1275 if (FP_REG_P (regno1
))
1276 ret
= "mov.d\t%0,%1";
1281 ret
= (TARGET_FLOAT64
)
1283 : "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";
1287 else if (FP_REG_P (regno1
))
1290 ret
= (TARGET_FLOAT64
)
1292 : "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";
1295 else if (MD_REG_P (regno0
) && GP_REG_P (regno1
))
1298 ret
= "mthi\t%M1\n\tmtlo\t%L1";
1301 else if (GP_REG_P (regno0
) && MD_REG_P (regno1
))
1304 ret
= "mfhi\t%M0\n\tmflo\t%L0";
1307 else if (regno0
!= (regno1
+1))
1308 ret
= "move\t%0,%1\n\tmove\t%D0,%D1";
1311 ret
= "move\t%D0,%D1\n\tmove\t%0,%1";
1314 else if (code1
== CONST_DOUBLE
)
1316 if (CONST_DOUBLE_HIGH (op1
) != 0 || CONST_DOUBLE_LOW (op1
) != 0)
1318 if (GET_MODE (op1
) == DFmode
)
1321 ret
= "li.d\t%0,%1";
1326 operands
[2] = GEN_INT (CONST_DOUBLE_LOW (op1
));
1327 operands
[3] = GEN_INT (CONST_DOUBLE_HIGH (op1
));
1328 ret
= "li\t%M0,%3\n\tli\t%L0,%2";
1334 if (GP_REG_P (regno0
))
1335 ret
= "move\t%0,%.\n\tmove\t%D0,%.";
1337 else if (FP_REG_P (regno0
))
1340 ret
= (TARGET_FLOAT64
)
1342 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1347 else if (code1
== CONST_INT
&& INTVAL (op1
) == 0)
1349 if (GP_REG_P (regno0
))
1350 ret
= "move\t%0,%.\n\tmove\t%D0,%.";
1352 else if (FP_REG_P (regno0
))
1355 ret
= (TARGET_FLOAT64
)
1357 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1361 else if (code1
== CONST_INT
&& GET_MODE (op0
) == DImode
&& GP_REG_P (regno0
))
1363 operands
[2] = GEN_INT (INTVAL (operands
[1]) >= 0 ? 0 : -1);
1364 ret
= "li\t%M0,%2\n\tli\t%L0,%1";
1367 else if (code1
== MEM
)
1372 mips_count_memory_refs (op1
, 2);
1374 if (FP_REG_P (regno0
))
1377 else if (offsettable_address_p (1, DFmode
, XEXP (op1
, 0)))
1379 operands
[2] = adj_offsettable_operand (op1
, 4);
1380 if (reg_mentioned_p (op0
, op1
))
1381 ret
= "lw\t%D0,%2\n\tlw\t%0,%1";
1383 ret
= "lw\t%0,%1\n\tlw\t%D0,%2";
1386 if (ret
!= (char *)0 && MEM_VOLATILE_P (op1
))
1388 int i
= strlen (ret
);
1389 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1392 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1393 ret
= volatile_buffer
;
1398 else if (code0
== MEM
)
1402 int regno1
= REGNO (op1
) + subreg_word1
;
1404 if (FP_REG_P (regno1
))
1407 else if (offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1409 operands
[2] = adj_offsettable_operand (op0
, 4);
1410 ret
= "sw\t%1,%0\n\tsw\t%D1,%2";
1414 else if (code1
== CONST_DOUBLE
1415 && CONST_DOUBLE_HIGH (op1
) == 0
1416 && CONST_DOUBLE_LOW (op1
) == 0
1417 && offsettable_address_p (1, DFmode
, XEXP (op0
, 0)))
1423 operands
[2] = adj_offsettable_operand (op0
, 4);
1424 ret
= "sw\t%.,%0\n\tsw\t%.,%2";
1429 mips_count_memory_refs (op0
, 2);
1431 if (ret
!= (char *)0 && MEM_VOLATILE_P (op0
))
1433 int i
= strlen (ret
);
1434 if (i
> sizeof (volatile_buffer
) - sizeof ("%{%}"))
1437 sprintf (volatile_buffer
, "%%{%s%%}", ret
);
1438 ret
= volatile_buffer
;
1442 if (ret
== (char *)0)
1444 abort_with_insn (insn
, "Bad move");
1448 if (delay
!= DELAY_NONE
)
1449 return mips_fill_delay_slot (ret
, delay
, operands
, insn
);
1455 /* Provide the costs of an addressing mode that contains ADDR.
1456 If ADDR is not a valid address, its cost is irrelevant. */
1459 mips_address_cost (addr
)
1462 switch (GET_CODE (addr
))
1476 rtx offset
= const0_rtx
;
1477 addr
= eliminate_constant_term (addr
, &offset
);
1478 if (GET_CODE (addr
) == LABEL_REF
)
1481 if (GET_CODE (addr
) != SYMBOL_REF
)
1484 if (INTVAL (offset
) < -32768 || INTVAL (offset
) > 32767)
1490 return SYMBOL_REF_FLAG (addr
) ? 1 : 2;
1494 register rtx plus0
= XEXP (addr
, 0);
1495 register rtx plus1
= XEXP (addr
, 1);
1497 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1499 plus0
= XEXP (addr
, 1);
1500 plus1
= XEXP (addr
, 0);
1503 if (GET_CODE (plus0
) != REG
)
1506 switch (GET_CODE (plus1
))
1513 int value
= INTVAL (plus1
);
1514 return (value
< -32768 || value
> 32767) ? 2 : 1;
1522 return mips_address_cost (plus1
) + 1;
1531 /* Make normal rtx_code into something we can index from an array */
1533 static enum internal_test
1534 map_test_to_internal_test (test_code
)
1535 enum rtx_code test_code
;
1537 enum internal_test test
= ITEST_MAX
;
1542 case EQ
: test
= ITEST_EQ
; break;
1543 case NE
: test
= ITEST_NE
; break;
1544 case GT
: test
= ITEST_GT
; break;
1545 case GE
: test
= ITEST_GE
; break;
1546 case LT
: test
= ITEST_LT
; break;
1547 case LE
: test
= ITEST_LE
; break;
1548 case GTU
: test
= ITEST_GTU
; break;
1549 case GEU
: test
= ITEST_GEU
; break;
1550 case LTU
: test
= ITEST_LTU
; break;
1551 case LEU
: test
= ITEST_LEU
; break;
1558 /* Generate the code to compare two integer values. The return value is:
1559 (reg:SI xx) The pseudo register the comparison is in
1560 (rtx)0 No register, generate a simple branch. */
1563 gen_int_relational (test_code
, result
, cmp0
, cmp1
, p_invert
)
1564 enum rtx_code test_code
; /* relational test (EQ, etc) */
1565 rtx result
; /* result to store comp. or 0 if branch */
1566 rtx cmp0
; /* first operand to compare */
1567 rtx cmp1
; /* second operand to compare */
1568 int *p_invert
; /* NULL or ptr to hold whether branch needs */
1569 /* to reverse its test */
1572 enum rtx_code test_code
; /* code to use in instruction (LT vs. LTU) */
1573 int const_low
; /* low bound of constant we can accept */
1574 int const_high
; /* high bound of constant we can accept */
1575 int const_add
; /* constant to add (convert LE -> LT) */
1576 int reverse_regs
; /* reverse registers in test */
1577 int invert_const
; /* != 0 if invert value if cmp1 is constant */
1578 int invert_reg
; /* != 0 if invert value if cmp1 is register */
1579 int unsignedp
; /* != 0 for unsigned comparisons. */
1582 static struct cmp_info info
[ (int)ITEST_MAX
] = {
1584 { XOR
, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1585 { XOR
, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1586 { LT
, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1587 { LT
, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1588 { LT
, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1589 { LT
, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1590 { LTU
, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1591 { LTU
, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1592 { LTU
, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1593 { LTU
, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1596 enum internal_test test
;
1597 struct cmp_info
*p_info
;
1604 test
= map_test_to_internal_test (test_code
);
1605 if (test
== ITEST_MAX
)
1608 p_info
= &info
[ (int)test
];
1609 eqne_p
= (p_info
->test_code
== XOR
);
1611 /* Eliminate simple branches */
1612 branch_p
= (result
== (rtx
)0);
1615 if (GET_CODE (cmp0
) == REG
|| GET_CODE (cmp0
) == SUBREG
)
1617 /* Comparisons against zero are simple branches */
1618 if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1621 /* Test for beq/bne. */
1626 /* allocate a pseudo to calculate the value in. */
1627 result
= gen_reg_rtx (SImode
);
1630 /* Make sure we can handle any constants given to us. */
1631 if (GET_CODE (cmp0
) == CONST_INT
)
1632 cmp0
= force_reg (SImode
, cmp0
);
1634 if (GET_CODE (cmp1
) == CONST_INT
)
1636 HOST_WIDE_INT value
= INTVAL (cmp1
);
1637 if (value
< p_info
->const_low
|| value
> p_info
->const_high
)
1638 cmp1
= force_reg (SImode
, cmp1
);
1641 /* See if we need to invert the result. */
1642 invert
= (GET_CODE (cmp1
) == CONST_INT
)
1643 ? p_info
->invert_const
1644 : p_info
->invert_reg
;
1646 if (p_invert
!= (int *)0)
1652 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1653 Comparison between two registers, may involve switching operands. */
1654 if (GET_CODE (cmp1
) == CONST_INT
)
1656 if (p_info
->const_add
!= 0)
1658 HOST_WIDE_INT
new = INTVAL (cmp1
) + p_info
->const_add
;
1659 /* If modification of cmp1 caused overflow,
1660 we would get the wrong answer if we follow the usual path;
1661 thus, x > 0xffffffffu would turn into x > 0u. */
1662 if ((p_info
->unsignedp
1663 ? (unsigned HOST_WIDE_INT
) new > INTVAL (cmp1
)
1664 : new > INTVAL (cmp1
))
1665 != (p_info
->const_add
> 0))
1667 /* This test is always true, but if INVERT is true then
1668 the result of the test needs to be inverted so 0 should
1669 be returned instead. */
1670 emit_move_insn (result
, invert
? const0_rtx
: const_true_rtx
);
1674 cmp1
= GEN_INT (new);
1677 else if (p_info
->reverse_regs
)
1684 if (test
== ITEST_NE
&& GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) == 0)
1688 reg
= (invert
|| eqne_p
) ? gen_reg_rtx (SImode
) : result
;
1689 emit_move_insn (reg
, gen_rtx (p_info
->test_code
, SImode
, cmp0
, cmp1
));
1692 if (test
== ITEST_NE
)
1694 emit_move_insn (result
, gen_rtx (GTU
, SImode
, reg
, const0_rtx
));
1698 else if (test
== ITEST_EQ
)
1700 reg2
= (invert
) ? gen_reg_rtx (SImode
) : result
;
1701 emit_move_insn (reg2
, gen_rtx (LTU
, SImode
, reg
, const1_rtx
));
1706 emit_move_insn (result
, gen_rtx (XOR
, SImode
, reg
, const1_rtx
));
1712 /* Emit the common code for doing conditional branches.
1713 operand[0] is the label to jump to.
1714 The comparison operands are saved away by cmp{si,sf,df}. */
1717 gen_conditional_branch (operands
, test_code
)
1719 enum rtx_code test_code
;
1721 static enum machine_mode mode_map
[(int)CMP_MAX
][(int)ITEST_MAX
] = {
1736 CC_REV_FPmode
, /* ne */
1748 CC_REV_FPmode
, /* ne */
1760 enum machine_mode mode
;
1761 enum cmp_type type
= branch_type
;
1762 rtx cmp0
= branch_cmp
[0];
1763 rtx cmp1
= branch_cmp
[1];
1764 rtx label1
= gen_rtx (LABEL_REF
, VOIDmode
, operands
[0]);
1765 rtx label2
= pc_rtx
;
1768 enum internal_test test
= map_test_to_internal_test (test_code
);
1770 if (test
== ITEST_MAX
)
1776 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
1777 mode
= mode_map
[(int)type
][(int)test
];
1778 if (mode
== VOIDmode
)
1781 switch (branch_type
)
1787 reg
= gen_int_relational (test_code
, (rtx
)0, cmp0
, cmp1
, &invert
);
1795 /* Make sure not non-zero constant if ==/!= */
1796 else if (GET_CODE (cmp1
) == CONST_INT
&& INTVAL (cmp1
) != 0)
1797 cmp1
= force_reg (SImode
, cmp1
);
1804 rtx reg
= gen_rtx (REG
, mode
, FPSW_REGNUM
);
1805 emit_insn (gen_rtx (SET
, VOIDmode
, reg
, gen_rtx (test_code
, mode
, cmp0
, cmp1
)));
1813 /* Generate the jump */
1820 emit_jump_insn (gen_rtx (SET
, VOIDmode
,
1822 gen_rtx (IF_THEN_ELSE
, VOIDmode
,
1823 gen_rtx (test_code
, mode
, cmp0
, cmp1
),
1830 abort_with_insn (gen_rtx (test_code
, mode
, cmp0
, cmp1
), "bad test");
1834 #define UNITS_PER_SHORT (SHORT_TYPE_SIZE / BITS_PER_UNIT)
1836 /* Internal code to generate the load and store of one word/short/byte.
1837 The load is emitted directly, and the store insn is returned. */
1841 block_move_load_store (dest_reg
, src_reg
, p_bytes
, p_offset
, align
, orig_src
)
1842 rtx src_reg
; /* register holding source memory address */
1843 rtx dest_reg
; /* register holding dest. memory address */
1844 int *p_bytes
; /* pointer to # bytes remaining */
1845 int *p_offset
; /* pointer to current offset */
1846 int align
; /* alignment */
1847 rtx orig_src
; /* original source for making a reg note */
1849 int bytes
; /* # bytes remaining */
1850 int offset
; /* offset to use */
1851 int size
; /* size in bytes of load/store */
1852 enum machine_mode mode
; /* mode to use for load/store */
1853 rtx reg
; /* temporary register */
1854 rtx src_addr
; /* source address */
1855 rtx dest_addr
; /* destination address */
1856 rtx insn
; /* insn of the load */
1857 rtx orig_src_addr
; /* original source address */
1858 rtx (*load_func
)(); /* function to generate load insn */
1859 rtx (*store_func
)(); /* function to generate destination insn */
1862 if (bytes
<= 0 || align
<= 0)
1865 if (bytes
>= UNITS_PER_WORD
&& align
>= UNITS_PER_WORD
)
1868 size
= UNITS_PER_WORD
;
1869 load_func
= gen_movsi
;
1870 store_func
= gen_movsi
;
1874 /* Don't generate unaligned moves here, rather defer those to the
1875 general movestrsi_internal pattern. */
1876 else if (bytes
>= UNITS_PER_WORD
)
1879 size
= UNITS_PER_WORD
;
1880 load_func
= gen_movsi_ulw
;
1881 store_func
= gen_movsi_usw
;
1885 else if (bytes
>= UNITS_PER_SHORT
&& align
>= UNITS_PER_SHORT
)
1888 size
= UNITS_PER_SHORT
;
1889 load_func
= gen_movhi
;
1890 store_func
= gen_movhi
;
1897 load_func
= gen_movqi
;
1898 store_func
= gen_movqi
;
1902 *p_offset
= offset
+ size
;
1903 *p_bytes
= bytes
- size
;
1908 dest_addr
= dest_reg
;
1912 src_addr
= gen_rtx (PLUS
, Pmode
, src_reg
, GEN_INT (offset
));
1913 dest_addr
= gen_rtx (PLUS
, Pmode
, dest_reg
, GEN_INT (offset
));
1916 reg
= gen_reg_rtx (mode
);
1917 insn
= emit_insn ((*load_func
) (reg
, gen_rtx (MEM
, mode
, src_addr
)));
1918 orig_src_addr
= XEXP (orig_src
, 0);
1919 if (CONSTANT_P (orig_src_addr
))
1920 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUIV
,
1921 plus_constant (orig_src_addr
, offset
),
1924 return (*store_func
) (gen_rtx (MEM
, mode
, dest_addr
), reg
);
1929 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows:
1941 This way, no NOP's are needed, except at the end, and only
1942 two temp registers are needed. Two delay slots are used
1943 in deference to the R4000. */
1947 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
)
1948 rtx dest_reg
; /* register holding destination address */
1949 rtx src_reg
; /* register holding source address */
1950 int bytes
; /* # bytes to move */
1951 int align
; /* max alignment to assume */
1952 rtx orig_src
; /* original source for making a reg note */
1955 rtx prev2_store
= (rtx
)0;
1956 rtx prev_store
= (rtx
)0;
1957 rtx cur_store
= (rtx
)0;
1961 /* Is there a store to do? */
1963 emit_insn (prev2_store
);
1965 prev2_store
= prev_store
;
1966 prev_store
= cur_store
;
1967 cur_store
= block_move_load_store (dest_reg
, src_reg
,
1972 /* Finish up last three stores. */
1974 emit_insn (prev2_store
);
1977 emit_insn (prev_store
);
1980 emit_insn (cur_store
);
1985 /* Write a loop to move a constant number of bytes. Generate load/stores as follows:
1991 temp<last> = src[MAX_MOVE_REGS-1];
1995 dest[MAX_MOVE_REGS-1] = temp<last>;
1996 src += MAX_MOVE_REGS;
1997 dest += MAX_MOVE_REGS;
1998 } while (src != final);
2000 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp
2001 registers are needed.
2003 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3
2004 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every
2005 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */
2007 #define MAX_MOVE_REGS 4
2008 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2011 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
)
2012 rtx dest_reg
; /* register holding destination address */
2013 rtx src_reg
; /* register holding source address */
2014 int bytes
; /* # bytes to move */
2015 int align
; /* alignment */
2016 rtx orig_src
; /* original source for making a reg note */
2018 rtx dest_mem
= gen_rtx (MEM
, BLKmode
, dest_reg
);
2019 rtx src_mem
= gen_rtx (MEM
, BLKmode
, src_reg
);
2020 rtx align_rtx
= GEN_INT (align
);
2026 if (bytes
< 2*MAX_MOVE_BYTES
)
2029 leftover
= bytes
% MAX_MOVE_BYTES
;
2032 label
= gen_label_rtx ();
2033 final_src
= gen_reg_rtx (Pmode
);
2034 bytes_rtx
= GEN_INT (bytes
);
2038 emit_insn (gen_movsi (final_src
, bytes_rtx
));
2039 emit_insn (gen_addsi3 (final_src
, final_src
, src_reg
));
2042 emit_insn (gen_addsi3 (final_src
, src_reg
, bytes_rtx
));
2046 bytes_rtx
= GEN_INT (MAX_MOVE_BYTES
);
2047 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
, bytes_rtx
, align_rtx
));
2048 emit_insn (gen_addsi3 (src_reg
, src_reg
, bytes_rtx
));
2049 emit_insn (gen_addsi3 (dest_reg
, dest_reg
, bytes_rtx
));
2050 emit_insn (gen_cmpsi (src_reg
, final_src
));
2051 emit_jump_insn (gen_bne (label
));
2054 emit_insn (gen_movstrsi_internal (dest_mem
, src_mem
,
2060 /* Use a library function to move some bytes. */
2063 block_move_call (dest_reg
, src_reg
, bytes_rtx
)
2068 #ifdef TARGET_MEM_FUNCTIONS
2069 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "memcpy"), 0,
2075 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "bcopy"), 0,
2084 /* Expand string/block move operations.
2086 operands[0] is the pointer to the destination.
2087 operands[1] is the pointer to the source.
2088 operands[2] is the number of bytes to move.
2089 operands[3] is the alignment. */
2092 expand_block_move (operands
)
2095 rtx bytes_rtx
= operands
[2];
2096 rtx align_rtx
= operands
[3];
2097 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
2098 int bytes
= (constp
? INTVAL (bytes_rtx
) : 0);
2099 int align
= INTVAL (align_rtx
);
2100 rtx orig_src
= operands
[1];
2104 if (constp
&& bytes
<= 0)
2107 if (align
> UNITS_PER_WORD
)
2108 align
= UNITS_PER_WORD
;
2110 /* Move the address into scratch registers. */
2111 dest_reg
= copy_addr_to_reg (XEXP (operands
[0], 0));
2112 src_reg
= copy_addr_to_reg (XEXP (orig_src
, 0));
2115 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2118 else if (constp
&& bytes
<= 3*align
)
2119 block_move_sequence (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2122 else if (constp
&& bytes
<= 2*MAX_MOVE_BYTES
)
2123 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2124 gen_rtx (MEM
, BLKmode
, src_reg
),
2125 bytes_rtx
, align_rtx
));
2127 else if (constp
&& align
>= UNITS_PER_WORD
&& optimize
)
2128 block_move_loop (dest_reg
, src_reg
, bytes
, align
, orig_src
);
2130 else if (constp
&& optimize
)
2132 /* If the alignment is not word aligned, generate a test at
2133 runtime, to see whether things wound up aligned, and we
2134 can use the faster lw/sw instead ulw/usw. */
2136 rtx temp
= gen_reg_rtx (Pmode
);
2137 rtx aligned_label
= gen_label_rtx ();
2138 rtx join_label
= gen_label_rtx ();
2139 int leftover
= bytes
% MAX_MOVE_BYTES
;
2143 emit_insn (gen_iorsi3 (temp
, src_reg
, dest_reg
));
2144 emit_insn (gen_andsi3 (temp
, temp
, GEN_INT (UNITS_PER_WORD
-1)));
2145 emit_insn (gen_cmpsi (temp
, const0_rtx
));
2146 emit_jump_insn (gen_beq (aligned_label
));
2148 /* Unaligned loop. */
2149 block_move_loop (dest_reg
, src_reg
, bytes
, 1, orig_src
);
2150 emit_jump_insn (gen_jump (join_label
));
2154 emit_label (aligned_label
);
2155 block_move_loop (dest_reg
, src_reg
, bytes
, UNITS_PER_WORD
, orig_src
);
2156 emit_label (join_label
);
2158 /* Bytes at the end of the loop. */
2162 if (leftover
<= 3*align
)
2163 block_move_sequence (dest_reg
, src_reg
, leftover
, align
, orig_src
);
2167 emit_insn (gen_movstrsi_internal (gen_rtx (MEM
, BLKmode
, dest_reg
),
2168 gen_rtx (MEM
, BLKmode
, src_reg
),
2175 block_move_call (dest_reg
, src_reg
, bytes_rtx
);
2179 /* Emit load/stores for a small constant block_move.
2181 operands[0] is the memory address of the destination.
2182 operands[1] is the memory address of the source.
2183 operands[2] is the number of bytes to move.
2184 operands[3] is the alignment.
2185 operands[4] is a temp register.
2186 operands[5] is a temp register.
2188 operands[3+num_regs] is the last temp register.
2190 The block move type can be one of the following:
2191 BLOCK_MOVE_NORMAL Do all of the block move.
2192 BLOCK_MOVE_NOT_LAST Do all but the last store.
2193 BLOCK_MOVE_LAST Do just the last store. */
2196 output_block_move (insn
, operands
, num_regs
, move_type
)
2200 enum block_move_type move_type
;
2202 rtx dest_reg
= XEXP (operands
[0], 0);
2203 rtx src_reg
= XEXP (operands
[1], 0);
2204 int bytes
= INTVAL (operands
[2]);
2205 int align
= INTVAL (operands
[3]);
2208 int use_lwl_lwr
= FALSE
;
2209 int last_operand
= num_regs
+4;
2215 char *load
; /* load insn without nop */
2216 char *load_nop
; /* load insn with trailing nop */
2217 char *store
; /* store insn */
2218 char *final
; /* if last_store used: NULL or swr */
2219 char *last_store
; /* last store instruction */
2220 int offset
; /* current offset */
2221 enum machine_mode mode
; /* mode to use on (MEM) */
2224 /* Detect a bug in GCC, where it can give us a register
2225 the same as one of the addressing registers and reduce
2226 the number of registers available. */
2228 i
< last_operand
&& safe_regs
< (sizeof(xoperands
) / sizeof(xoperands
[0]));
2231 if (!reg_mentioned_p (operands
[i
], operands
[0])
2232 && !reg_mentioned_p (operands
[i
], operands
[1]))
2234 xoperands
[safe_regs
++] = operands
[i
];
2237 if (safe_regs
< last_operand
)
2239 xoperands
[0] = operands
[0];
2240 xoperands
[1] = operands
[1];
2241 xoperands
[2] = operands
[2];
2242 xoperands
[3] = operands
[3];
2243 return output_block_move (insn
, xoperands
, safe_regs
-4, move_type
);
2246 /* If we are given global or static addresses, and we would be
2247 emitting a few instructions, try to save time by using a
2248 temporary register for the pointer. */
2249 if (num_regs
> 2 && (bytes
> 2*align
|| move_type
!= BLOCK_MOVE_NORMAL
))
2251 if (CONSTANT_P (src_reg
))
2254 mips_count_memory_refs (operands
[1], 1);
2256 src_reg
= operands
[ 3 + num_regs
-- ];
2257 if (move_type
!= BLOCK_MOVE_LAST
)
2259 xoperands
[1] = operands
[1];
2260 xoperands
[0] = src_reg
;
2261 output_asm_insn ("la\t%0,%1", xoperands
);
2265 if (CONSTANT_P (dest_reg
))
2268 mips_count_memory_refs (operands
[0], 1);
2270 dest_reg
= operands
[ 3 + num_regs
-- ];
2271 if (move_type
!= BLOCK_MOVE_LAST
)
2273 xoperands
[1] = operands
[0];
2274 xoperands
[0] = dest_reg
;
2275 output_asm_insn ("la\t%0,%1", xoperands
);
2280 if (num_regs
> (sizeof (load_store
) / sizeof (load_store
[0])))
2281 num_regs
= (sizeof (load_store
) / sizeof (load_store
[0]));
2283 else if (num_regs
< 1)
2284 abort_with_insn (insn
, "Cannot do block move, not enough scratch registers");
2286 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& set_noreorder
++ == 0)
2287 output_asm_insn (".set\tnoreorder", operands
);
2291 load_store
[num
].offset
= offset
;
2293 if (bytes
>= UNITS_PER_WORD
&& align
>= UNITS_PER_WORD
)
2295 load_store
[num
].load
= "lw\t%0,%1";
2296 load_store
[num
].load_nop
= "lw\t%0,%1%#";
2297 load_store
[num
].store
= "sw\t%0,%1";
2298 load_store
[num
].last_store
= "sw\t%0,%1";
2299 load_store
[num
].final
= (char *)0;
2300 load_store
[num
].mode
= SImode
;
2301 offset
+= UNITS_PER_WORD
;
2302 bytes
-= UNITS_PER_WORD
;
2305 else if (bytes
>= UNITS_PER_WORD
)
2307 #if BYTES_BIG_ENDIAN
2308 load_store
[num
].load
= "lwl\t%0,%1\n\tlwr\t%0,%2";
2309 load_store
[num
].load_nop
= "lwl\t%0,%1\n\tlwr\t%0,%2%#";
2310 load_store
[num
].store
= "swl\t%0,%1\n\tswr\t%0,%2";
2311 load_store
[num
].last_store
= "swr\t%0,%2";
2312 load_store
[num
].final
= "swl\t%0,%1";
2314 load_store
[num
].load
= "lwl\t%0,%2\n\tlwr\t%0,%1";
2315 load_store
[num
].load_nop
= "lwl\t%0,%2\n\tlwr\t%0,%1%#";
2316 load_store
[num
].store
= "swl\t%0,%2\n\tswr\t%0,%1";
2317 load_store
[num
].last_store
= "swr\t%0,%1";
2318 load_store
[num
].final
= "swl\t%0,%2";
2320 load_store
[num
].mode
= SImode
;
2321 offset
+= UNITS_PER_WORD
;
2322 bytes
-= UNITS_PER_WORD
;
2326 else if (bytes
>= UNITS_PER_SHORT
&& align
>= UNITS_PER_SHORT
)
2328 load_store
[num
].load
= "lh\t%0,%1";
2329 load_store
[num
].load_nop
= "lh\t%0,%1%#";
2330 load_store
[num
].store
= "sh\t%0,%1";
2331 load_store
[num
].last_store
= "sh\t%0,%1";
2332 load_store
[num
].final
= (char *)0;
2333 load_store
[num
].offset
= offset
;
2334 load_store
[num
].mode
= HImode
;
2335 offset
+= UNITS_PER_SHORT
;
2336 bytes
-= UNITS_PER_SHORT
;
2341 load_store
[num
].load
= "lb\t%0,%1";
2342 load_store
[num
].load_nop
= "lb\t%0,%1%#";
2343 load_store
[num
].store
= "sb\t%0,%1";
2344 load_store
[num
].last_store
= "sb\t%0,%1";
2345 load_store
[num
].final
= (char *)0;
2346 load_store
[num
].mode
= QImode
;
2351 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2353 dslots_load_total
++;
2354 dslots_load_filled
++;
2356 if (CONSTANT_P (src_reg
))
2357 mips_count_memory_refs (src_reg
, 1);
2359 if (CONSTANT_P (dest_reg
))
2360 mips_count_memory_refs (dest_reg
, 1);
2363 /* Emit load/stores now if we have run out of registers or are
2364 at the end of the move. */
2366 if (++num
== num_regs
|| bytes
== 0)
2368 /* If only load/store, we need a NOP after the load. */
2371 load_store
[0].load
= load_store
[0].load_nop
;
2372 if (TARGET_STATS
&& move_type
!= BLOCK_MOVE_LAST
)
2373 dslots_load_filled
--;
2376 if (move_type
!= BLOCK_MOVE_LAST
)
2378 for (i
= 0; i
< num
; i
++)
2385 if (GET_MODE (operands
[i
+4]) != load_store
[i
].mode
)
2386 operands
[i
+4] = gen_rtx (REG
, load_store
[i
].mode
, REGNO (operands
[i
+4]));
2388 offset
= load_store
[i
].offset
;
2389 xoperands
[0] = operands
[i
+4];
2390 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2391 plus_constant (src_reg
, offset
));
2394 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2395 plus_constant (src_reg
, UNITS_PER_WORD
-1+offset
));
2397 output_asm_insn (load_store
[i
].load
, xoperands
);
2401 for (i
= 0; i
< num
; i
++)
2403 int last_p
= (i
== num
-1 && bytes
== 0);
2404 int offset
= load_store
[i
].offset
;
2406 xoperands
[0] = operands
[i
+4];
2407 xoperands
[1] = gen_rtx (MEM
, load_store
[i
].mode
,
2408 plus_constant (dest_reg
, offset
));
2412 xoperands
[2] = gen_rtx (MEM
, load_store
[i
].mode
,
2413 plus_constant (dest_reg
, UNITS_PER_WORD
-1+offset
));
2415 if (move_type
== BLOCK_MOVE_NORMAL
)
2416 output_asm_insn (load_store
[i
].store
, xoperands
);
2418 else if (move_type
== BLOCK_MOVE_NOT_LAST
)
2421 output_asm_insn (load_store
[i
].store
, xoperands
);
2423 else if (load_store
[i
].final
!= (char *)0)
2424 output_asm_insn (load_store
[i
].final
, xoperands
);
2428 output_asm_insn (load_store
[i
].last_store
, xoperands
);
2431 num
= 0; /* reset load_store */
2432 use_lwl_lwr
= FALSE
; /* reset whether or not we used lwl/lwr */
2436 if (TARGET_GAS
&& move_type
!= BLOCK_MOVE_LAST
&& --set_noreorder
== 0)
2437 output_asm_insn (".set\treorder", operands
);
2443 /* Argument support functions. */
2445 /* Initialize CUMULATIVE_ARGS for a function. */
2448 init_cumulative_args (cum
, fntype
, libname
)
2449 CUMULATIVE_ARGS
*cum
; /* argument info to initialize */
2450 tree fntype
; /* tree ptr for function decl */
2451 rtx libname
; /* SYMBOL_REF of library name or 0 */
2453 static CUMULATIVE_ARGS zero_cum
;
2454 tree param
, next_param
;
2456 if (TARGET_DEBUG_E_MODE
)
2458 fprintf (stderr
, "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype
);
2460 fputc ('\n', stderr
);
2464 tree ret_type
= TREE_TYPE (fntype
);
2465 fprintf (stderr
, ", fntype code = %s, ret code = %s\n",
2466 tree_code_name
[ (int)TREE_CODE (fntype
) ],
2467 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
2473 /* Determine if this function has variable arguments. This is
2474 indicated by the last argument being 'void_type_mode' if there
2475 are no variable arguments. The standard MIPS calling sequence
2476 passes all arguments in the general purpose registers in this
2479 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
2483 next_param
= TREE_CHAIN (param
);
2484 if (next_param
== (tree
)0 && TREE_VALUE (param
) != void_type_node
)
2485 cum
->gp_reg_found
= 1;
2489 /* Advance the argument to the next argument position. */
2492 function_arg_advance (cum
, mode
, type
, named
)
2493 CUMULATIVE_ARGS
*cum
; /* current arg information */
2494 enum machine_mode mode
; /* current arg mode */
2495 tree type
; /* type of the argument or 0 if lib support */
2496 int named
; /* whether or not the argument was named */
2498 if (TARGET_DEBUG_E_MODE
)
2500 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n\n",
2501 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2508 error ("Illegal mode given to function_arg_advance");
2515 cum
->gp_reg_found
= 1;
2516 cum
->arg_words
+= (int_size_in_bytes (type
) + 3) / 4;
2524 cum
->arg_words
+= 2;
2528 cum
->gp_reg_found
= 1;
2529 cum
->arg_words
+= 2;
2535 cum
->gp_reg_found
= 1;
2541 /* Return a RTL expression containing the register for the given mode,
2542 or 0 if the argument is too be passed on the stack. */
2545 function_arg (cum
, mode
, type
, named
)
2546 CUMULATIVE_ARGS
*cum
; /* current arg information */
2547 enum machine_mode mode
; /* current arg mode */
2548 tree type
; /* type of the argument or 0 if lib support */
2549 int named
; /* != 0 for normal args, == 0 for ... args */
2554 int struct_p
= ((type
!= (tree
)0)
2555 && (TREE_CODE (type
) == RECORD_TYPE
2556 || TREE_CODE (type
) == UNION_TYPE
));
2558 if (TARGET_DEBUG_E_MODE
)
2560 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ",
2561 cum
->gp_reg_found
, cum
->arg_number
, cum
->arg_words
, GET_MODE_NAME (mode
),
2567 error ("Illegal mode given to function_arg");
2571 if (cum
->gp_reg_found
|| cum
->arg_number
>= 2)
2572 regbase
= GP_ARG_FIRST
;
2574 regbase
= (TARGET_SOFT_FLOAT
) ? GP_ARG_FIRST
: FP_ARG_FIRST
;
2575 if (cum
->arg_words
== 1) /* first arg was float */
2576 bias
= 1; /* use correct reg */
2582 cum
->arg_words
+= (cum
->arg_words
& 1);
2583 regbase
= (cum
->gp_reg_found
|| TARGET_SOFT_FLOAT
|| cum
->arg_number
>= 2
2589 if (type
!= (tree
)0 && TYPE_ALIGN (type
) > BITS_PER_WORD
)
2590 cum
->arg_words
+= (cum
->arg_words
& 1);
2592 regbase
= GP_ARG_FIRST
;
2599 regbase
= GP_ARG_FIRST
;
2603 cum
->arg_words
+= (cum
->arg_words
& 1);
2604 regbase
= GP_ARG_FIRST
;
2607 if (cum
->arg_words
>= MAX_ARGS_IN_REGISTERS
)
2609 if (TARGET_DEBUG_E_MODE
)
2610 fprintf (stderr
, "<stack>%s\n", struct_p
? ", [struct]" : "");
2619 ret
= gen_rtx (REG
, mode
, regbase
+ cum
->arg_words
+ bias
);
2621 if (TARGET_DEBUG_E_MODE
)
2622 fprintf (stderr
, "%s%s\n", reg_names
[regbase
+ cum
->arg_words
+ bias
],
2623 struct_p
? ", [struct]" : "");
2625 /* The following is a hack in order to pass 1 byte structures
2626 the same way that the MIPS compiler does (namely by passing
2627 the structure in the high byte or half word of the register).
2628 This also makes varargs work. If we have such a structure,
2629 we save the adjustment RTL, and the call define expands will
2630 emit them. For the VOIDmode argument (argument after the
2631 last real argument, pass back a parallel vector holding each
2632 of the adjustments. */
2634 /* ??? function_arg can be called more than once for each argument.
2635 As a result, we compute more adjustments than we need here.
2636 See the CUMULATIVE_ARGS definition in mips.h. */
2638 if (struct_p
&& int_size_in_bytes (type
) < 4)
2640 rtx amount
= GEN_INT (BITS_PER_WORD
2641 - int_size_in_bytes (type
) * BITS_PER_UNIT
);
2642 rtx reg
= gen_rtx (REG
, SImode
, regbase
+ cum
->arg_words
+ bias
);
2643 cum
->adjust
[ cum
->num_adjusts
++ ] = gen_ashlsi3 (reg
, reg
, amount
);
2647 if (mode
== VOIDmode
&& cum
->num_adjusts
> 0)
2648 ret
= gen_rtx (PARALLEL
, VOIDmode
, gen_rtvec_v (cum
->num_adjusts
, cum
->adjust
));
2655 function_arg_partial_nregs (cum
, mode
, type
, named
)
2656 CUMULATIVE_ARGS
*cum
; /* current arg information */
2657 enum machine_mode mode
; /* current arg mode */
2658 tree type
; /* type of the argument or 0 if lib support */
2659 int named
; /* != 0 for normal args, == 0 for ... args */
2661 if (mode
== BLKmode
&& cum
->arg_words
< MAX_ARGS_IN_REGISTERS
)
2663 int words
= (int_size_in_bytes (type
) + 3) / 4;
2665 if (words
+ cum
->arg_words
<= MAX_ARGS_IN_REGISTERS
)
2666 return 0; /* structure fits in registers */
2668 if (TARGET_DEBUG_E_MODE
)
2669 fprintf (stderr
, "function_arg_partial_nregs = %d\n",
2670 MAX_ARGS_IN_REGISTERS
- cum
->arg_words
);
2672 return MAX_ARGS_IN_REGISTERS
- cum
->arg_words
;
2675 else if (mode
== DImode
&& cum
->arg_words
== MAX_ARGS_IN_REGISTERS
-1)
2677 if (TARGET_DEBUG_E_MODE
)
2678 fprintf (stderr
, "function_arg_partial_nregs = 1\n");
2687 /* Print the options used in the assembly file. */
2689 static struct {char *name
; int value
;} target_switches
[]
2700 int mask
= TARGET_DEFAULT
;
2702 /* Allow assembly language comparisons with -mdebug eliminating the
2703 compiler version number and switch lists. */
2705 if (TARGET_DEBUG_MODE
)
2708 fprintf (out
, "\n # %s %s", language_string
, version_string
);
2709 #ifdef TARGET_VERSION_INTERNAL
2710 TARGET_VERSION_INTERNAL (out
);
2713 fprintf (out
, " compiled by GNU C\n\n");
2715 fprintf (out
, " compiled by CC\n\n");
2718 fprintf (out
, " # Cc1 defaults:");
2720 for (j
= 0; j
< sizeof target_switches
/ sizeof target_switches
[0]; j
++)
2722 if (target_switches
[j
].name
[0] != '\0'
2723 && target_switches
[j
].value
> 0
2724 && (target_switches
[j
].value
& mask
) == target_switches
[j
].value
)
2726 mask
&= ~ target_switches
[j
].value
;
2727 len
= strlen (target_switches
[j
].name
) + 1;
2728 if (len
+ line_len
> 79)
2731 fputs ("\n #", out
);
2733 fprintf (out
, " -m%s", target_switches
[j
].name
);
2738 fprintf (out
, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):",
2739 mips_section_threshold
, mips_cpu_string
, mips_isa
);
2742 for (p
= &save_argv
[1]; *p
!= (char *)0; p
++)
2747 len
= strlen (arg
) + 1;
2748 if (len
+ line_len
> 79)
2751 fputs ("\n #", out
);
2753 fprintf (out
, " %s", *p
);
2758 fputs ("\n\n", out
);
2762 /* Abort after printing out a specific insn. */
2765 abort_with_insn (insn
, reason
)
2774 /* Write a message to stderr (for use in macros expanded in files that do not
2775 include stdio.h). */
2781 fprintf (stderr
, s
, s1
, s2
);
2791 fprintf (stderr
, "compiling '%s' in '%s'\n",
2792 (current_function_name
!= (char *)0) ? current_function_name
: "<toplevel>",
2793 (current_function_file
!= (char *)0) ? current_function_file
: "<no file>");
2796 #endif /* SIGINFO */
2799 /* Set up the threshold for data to go into the small data area, instead
2800 of the normal data area, and detect any conflicts in the switches. */
2805 register int i
, start
;
2807 register enum machine_mode mode
;
2809 mips_section_threshold
= (g_switch_set
) ? g_switch_value
: MIPS_DEFAULT_GVALUE
;
2811 /* Identify the processor type */
2812 if (mips_cpu_string
== (char *)0
2813 || !strcmp (mips_cpu_string
, "default")
2814 || !strcmp (mips_cpu_string
, "DEFAULT"))
2816 mips_cpu_string
= "default";
2817 mips_cpu
= PROCESSOR_DEFAULT
;
2822 char *p
= mips_cpu_string
;
2824 if (*p
== 'r' || *p
== 'R')
2827 /* Since there is no difference between a R2000 and R3000 in
2828 terms of the scheduler, we collapse them into just an R3000. */
2830 mips_cpu
= PROCESSOR_DEFAULT
;
2834 if (!strcmp (p
, "2000") || !strcmp (p
, "2k") || !strcmp (p
, "2K"))
2835 mips_cpu
= PROCESSOR_R3000
;
2839 if (!strcmp (p
, "3000") || !strcmp (p
, "3k") || !strcmp (p
, "3K"))
2840 mips_cpu
= PROCESSOR_R3000
;
2844 if (!strcmp (p
, "4000") || !strcmp (p
, "4k") || !strcmp (p
, "4K"))
2845 mips_cpu
= PROCESSOR_R4000
;
2849 if (!strcmp (p
, "6000") || !strcmp (p
, "6k") || !strcmp (p
, "6K"))
2850 mips_cpu
= PROCESSOR_R6000
;
2854 if (mips_cpu
== PROCESSOR_DEFAULT
)
2856 error ("bad value (%s) for -mcpu= switch", mips_cpu_string
);
2857 mips_cpu_string
= "default";
2861 /* Now get the architectural level. */
2862 if (mips_isa_string
== (char *)0)
2865 else if (isdigit (*mips_isa_string
))
2866 mips_isa
= atoi (mips_isa_string
);
2870 error ("bad value (%s) for -mips switch", mips_isa_string
);
2874 if (mips_isa
< 0 || mips_isa
> 3)
2875 error ("-mips%d not supported", mips_isa
);
2877 else if (mips_isa
> 1
2878 && (mips_cpu
== PROCESSOR_DEFAULT
|| mips_cpu
== PROCESSOR_R3000
))
2879 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
2881 else if (mips_cpu
== PROCESSOR_R6000
&& mips_isa
> 2)
2882 error ("-mcpu=%s does not support -mips%d", mips_cpu_string
, mips_isa
);
2884 /* make sure sizes of ints/longs/etc. are ok */
2888 fatal ("Only the r4000 can support 64 bit ints");
2890 else if (TARGET_LONG64
)
2891 fatal ("Only the r4000 can support 64 bit longs");
2893 else if (TARGET_LLONG128
)
2894 fatal ("Only the r4000 can support 128 bit long longs");
2896 else if (TARGET_FLOAT64
)
2897 fatal ("Only the r4000 can support 64 bit fp registers");
2899 else if (TARGET_INT64
|| TARGET_LONG64
|| TARGET_LLONG128
|| TARGET_FLOAT64
)
2900 warning ("r4000 64/128 bit types not yet supported");
2902 /* Tell halfpic.c that we have half-pic code if we do. */
2903 if (TARGET_HALF_PIC
)
2906 if (TARGET_ABICALLS
)
2907 mips_abicalls
= MIPS_ABICALLS_YES
;
2909 mips_abicalls
= MIPS_ABICALLS_NO
;
2911 /* -mrnames says to use the MIPS software convention for register
2912 names instead of the hardware names (ie, a0 instead of $4).
2913 We do this by switching the names in mips_reg_names, which the
2914 reg_names points into via the REGISTER_NAMES macro. */
2916 if (TARGET_NAME_REGS
)
2920 target_flags
&= ~ MASK_NAME_REGS
;
2921 error ("Gas does not support the MIPS software register name convention.");
2924 bcopy ((char *) mips_sw_reg_names
, (char *) mips_reg_names
, sizeof (mips_reg_names
));
2927 /* If this is OSF/1, set up a SIGINFO handler so we can see what function
2928 is currently being compiled. */
2930 if (getenv ("GCC_SIGINFO") != (char *)0)
2932 struct sigaction action
;
2933 action
.sa_handler
= siginfo
;
2935 action
.sa_flags
= SA_RESTART
;
2936 sigaction (SIGINFO
, &action
, (struct sigaction
*)0);
2941 #if defined(ultrix) || defined(__ultrix) || defined(__OSF1__) || defined(__osf__) || defined(osf)
2942 /* If -mstats and -quiet, make stderr line buffered. */
2943 if (quiet_flag
&& TARGET_STATS
)
2944 setvbuf (stderr
, (char *)0, _IOLBF
, BUFSIZ
);
2948 /* Set up the classification arrays now. */
2949 mips_rtx_classify
[(int)PLUS
] = CLASS_ADD_OP
;
2950 mips_rtx_classify
[(int)MINUS
] = CLASS_ADD_OP
;
2951 mips_rtx_classify
[(int)DIV
] = CLASS_DIVMOD_OP
;
2952 mips_rtx_classify
[(int)MOD
] = CLASS_DIVMOD_OP
;
2953 mips_rtx_classify
[(int)UDIV
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
2954 mips_rtx_classify
[(int)UMOD
] = CLASS_DIVMOD_OP
| CLASS_UNSIGNED_OP
;
2955 mips_rtx_classify
[(int)EQ
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
2956 mips_rtx_classify
[(int)NE
] = CLASS_CMP_OP
| CLASS_EQUALITY_OP
| CLASS_FCMP_OP
;
2957 mips_rtx_classify
[(int)GT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2958 mips_rtx_classify
[(int)GE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2959 mips_rtx_classify
[(int)LT
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2960 mips_rtx_classify
[(int)LE
] = CLASS_CMP_OP
| CLASS_FCMP_OP
;
2961 mips_rtx_classify
[(int)GTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2962 mips_rtx_classify
[(int)GEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2963 mips_rtx_classify
[(int)LTU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2964 mips_rtx_classify
[(int)LEU
] = CLASS_CMP_OP
| CLASS_UNSIGNED_OP
;
2966 mips_print_operand_punct
['?'] = TRUE
;
2967 mips_print_operand_punct
['#'] = TRUE
;
2968 mips_print_operand_punct
['&'] = TRUE
;
2969 mips_print_operand_punct
['!'] = TRUE
;
2970 mips_print_operand_punct
['*'] = TRUE
;
2971 mips_print_operand_punct
['@'] = TRUE
;
2972 mips_print_operand_punct
['.'] = TRUE
;
2973 mips_print_operand_punct
['('] = TRUE
;
2974 mips_print_operand_punct
[')'] = TRUE
;
2975 mips_print_operand_punct
['['] = TRUE
;
2976 mips_print_operand_punct
[']'] = TRUE
;
2977 mips_print_operand_punct
['<'] = TRUE
;
2978 mips_print_operand_punct
['>'] = TRUE
;
2979 mips_print_operand_punct
['{'] = TRUE
;
2980 mips_print_operand_punct
['}'] = TRUE
;
2981 mips_print_operand_punct
['^'] = TRUE
;
2983 mips_char_to_class
['d'] = GR_REGS
;
2984 mips_char_to_class
['f'] = ((TARGET_HARD_FLOAT
) ? FP_REGS
: NO_REGS
);
2985 mips_char_to_class
['h'] = HI_REG
;
2986 mips_char_to_class
['l'] = LO_REG
;
2987 mips_char_to_class
['x'] = MD_REGS
;
2988 mips_char_to_class
['y'] = GR_REGS
;
2989 mips_char_to_class
['z'] = ST_REGS
;
2991 /* Set up array to map GCC register number to debug register number.
2992 Ignore the special purpose register numbers. */
2994 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2995 mips_dbx_regno
[i
] = -1;
2997 start
= GP_DBX_FIRST
- GP_REG_FIRST
;
2998 for (i
= GP_REG_FIRST
; i
<= GP_REG_LAST
; i
++)
2999 mips_dbx_regno
[i
] = i
+ start
;
3001 start
= FP_DBX_FIRST
- FP_REG_FIRST
;
3002 for (i
= FP_REG_FIRST
; i
<= FP_REG_LAST
; i
++)
3003 mips_dbx_regno
[i
] = i
+ start
;
3005 /* Set up array giving whether a given register can hold a given mode.
3006 At present, restrict ints from being in FP registers, because reload
3007 is a little enthusiastic about storing extra values in FP registers,
3008 and this is not good for things like OS kernels. Also, due to the
3009 mandatory delay, it is as fast to load from cached memory as to move
3010 from the FP register. */
3012 for (mode
= VOIDmode
;
3013 mode
!= MAX_MACHINE_MODE
;
3014 mode
= (enum machine_mode
)((int)mode
+ 1))
3016 register int size
= GET_MODE_SIZE (mode
);
3017 register enum mode_class
class = GET_MODE_CLASS (mode
);
3019 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
3023 if (mode
== CC_FPmode
|| mode
== CC_REV_FPmode
)
3024 temp
= (regno
== FPSW_REGNUM
);
3026 else if (GP_REG_P (regno
))
3027 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
3029 else if (FP_REG_P (regno
))
3030 temp
= ((TARGET_FLOAT64
|| ((regno
& 1) == 0))
3031 && (class == MODE_FLOAT
3032 || class == MODE_COMPLEX_FLOAT
3033 || (TARGET_DEBUG_H_MODE
&& class == MODE_INT
)));
3035 else if (MD_REG_P (regno
))
3036 temp
= (mode
== SImode
|| (regno
== MD_REG_FIRST
&& mode
== DImode
));
3041 mips_hard_regno_mode_ok
[(int)mode
][regno
] = temp
;
3048 * The MIPS debug format wants all automatic variables and arguments
3049 * to be in terms of the virtual frame pointer (stack pointer before
3050 * any adjustment in the function), while the MIPS 3.0 linker wants
3051 * the frame pointer to be the stack pointer after the initial
3052 * adjustment. So, we do the adjustment here. The arg pointer (which
3053 * is eliminated) points to the virtual frame pointer, while the frame
3054 * pointer (which may be eliminated) points to the stack pointer after
3055 * the initial adjustments.
3059 mips_debugger_offset (addr
, offset
)
3063 rtx offset2
= const0_rtx
;
3064 rtx reg
= eliminate_constant_term (addr
, &offset2
);
3067 offset
= INTVAL (offset2
);
3069 if (reg
== stack_pointer_rtx
|| reg
== frame_pointer_rtx
)
3071 int frame_size
= (!current_frame_info
.initialized
)
3072 ? compute_frame_size (get_frame_size ())
3073 : current_frame_info
.total_size
;
3075 offset
= offset
- frame_size
;
3077 /* sdbout_parms does not want this to crash for unrecognized cases. */
3079 else if (reg
!= arg_pointer_rtx
)
3080 abort_with_insn (addr
, "mips_debugger_offset called with non stack/frame/arg pointer.");
3087 /* A C compound statement to output to stdio stream STREAM the
3088 assembler syntax for an instruction operand X. X is an RTL
3091 CODE is a value that can be used to specify one of several ways
3092 of printing the operand. It is used when identical operands
3093 must be printed differently depending on the context. CODE
3094 comes from the `%' specification that was used to request
3095 printing of the operand. If the specification was just `%DIGIT'
3096 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3097 is the ASCII code for LTR.
3099 If X is a register, this macro should print the register's name.
3100 The names can be found in an array `reg_names' whose type is
3101 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3103 When the machine description has a specification `%PUNCT' (a `%'
3104 followed by a punctuation character), this macro is called with
3105 a null pointer for X and the punctuation character for CODE.
3107 The MIPS specific codes are:
3109 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
3110 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
3111 'd' output integer constant in decimal,
3112 'z' if the operand is 0, use $0 instead of normal operand.
3113 'D' print second register of double-word register operand.
3114 'L' print low-order register of double-word register operand.
3115 'M' print high-order register of double-word register operand.
3116 'C' print part of opcode for a branch condition.
3117 'N' print part of opcode for a branch condition, inverted.
3118 '(' Turn on .set noreorder
3119 ')' Turn on .set reorder
3120 '[' Turn on .set noat
3122 '<' Turn on .set nomacro
3123 '>' Turn on .set macro
3124 '{' Turn on .set volatile (not GAS)
3125 '}' Turn on .set novolatile (not GAS)
3126 '&' Turn on .set noreorder if filling delay slots
3127 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
3128 '!' Turn on .set nomacro if filling delay slots
3129 '#' Print nop if in a .set noreorder section.
3130 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3131 '@' Print the name of the assembler temporary register (at or $1).
3132 '.' Print the name of the register with a hard-wired zero (zero or $0).
3133 '^' Print the name of the pic call-through register (t9 or $25). */
3136 print_operand (file
, op
, letter
)
3137 FILE *file
; /* file to write to */
3138 rtx op
; /* operand to print */
3139 int letter
; /* %<letter> or 0 */
3141 register enum rtx_code code
;
3143 if (PRINT_OPERAND_PUNCT_VALID_P (letter
))
3148 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter
);
3152 if (mips_branch_likely
)
3157 fputs (reg_names
[GP_REG_FIRST
+ 1], file
);
3161 fputs (reg_names
[PIC_FUNCTION_ADDR_REGNUM
], file
);
3165 fputs (reg_names
[GP_REG_FIRST
+ 0], file
);
3169 if (final_sequence
!= 0 && set_noreorder
++ == 0)
3170 fputs (".set\tnoreorder\n\t", file
);
3174 if (final_sequence
!= 0)
3176 if (set_noreorder
++ == 0)
3177 fputs (".set\tnoreorder\n\t", file
);
3179 if (set_nomacro
++ == 0)
3180 fputs (".set\tnomacro\n\t", file
);
3185 if (final_sequence
!= 0 && set_nomacro
++ == 0)
3186 fputs ("\n\t.set\tnomacro", file
);
3190 if (set_noreorder
!= 0)
3191 fputs ("\n\tnop", file
);
3193 else if (TARGET_GAS
|| TARGET_STATS
)
3194 fputs ("\n\t#nop", file
);
3199 if (set_noreorder
++ == 0)
3200 fputs (".set\tnoreorder\n\t", file
);
3204 if (set_noreorder
== 0)
3205 error ("internal error: %%) found without a %%( in assembler pattern");
3207 else if (--set_noreorder
== 0)
3208 fputs ("\n\t.set\treorder", file
);
3213 if (set_noat
++ == 0)
3214 fputs (".set\tnoat\n\t", file
);
3219 error ("internal error: %%] found without a %%[ in assembler pattern");
3221 else if (--set_noat
== 0)
3222 fputs ("\n\t.set\tat", file
);
3227 if (set_nomacro
++ == 0)
3228 fputs (".set\tnomacro\n\t", file
);
3232 if (set_nomacro
== 0)
3233 error ("internal error: %%> found without a %%< in assembler pattern");
3235 else if (--set_nomacro
== 0)
3236 fputs ("\n\t.set\tmacro", file
);
3241 if (set_volatile
++ == 0)
3242 fprintf (file
, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS
) ? "" : "#");
3246 if (set_volatile
== 0)
3247 error ("internal error: %%} found without a %%{ in assembler pattern");
3249 else if (--set_volatile
== 0)
3250 fprintf (file
, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS
) ? "" : "#");
3259 error ("PRINT_OPERAND null pointer");
3263 code
= GET_CODE (op
);
3267 case EQ
: fputs ("eq", file
); break;
3268 case NE
: fputs ("ne", file
); break;
3269 case GT
: fputs ("gt", file
); break;
3270 case GE
: fputs ("ge", file
); break;
3271 case LT
: fputs ("lt", file
); break;
3272 case LE
: fputs ("le", file
); break;
3273 case GTU
: fputs ("gtu", file
); break;
3274 case GEU
: fputs ("geu", file
); break;
3275 case LTU
: fputs ("ltu", file
); break;
3276 case LEU
: fputs ("leu", file
); break;
3279 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%C");
3282 else if (letter
== 'N')
3285 case EQ
: fputs ("ne", file
); break;
3286 case NE
: fputs ("eq", file
); break;
3287 case GT
: fputs ("le", file
); break;
3288 case GE
: fputs ("lt", file
); break;
3289 case LT
: fputs ("ge", file
); break;
3290 case LE
: fputs ("gt", file
); break;
3291 case GTU
: fputs ("leu", file
); break;
3292 case GEU
: fputs ("ltu", file
); break;
3293 case LTU
: fputs ("geu", file
); break;
3294 case LEU
: fputs ("gtu", file
); break;
3297 abort_with_insn (op
, "PRINT_OPERAND, illegal insn for %%N");
3300 else if (code
== REG
)
3302 register int regnum
= REGNO (op
);
3305 regnum
+= MOST_SIGNIFICANT_WORD
;
3307 else if (letter
== 'L')
3308 regnum
+= LEAST_SIGNIFICANT_WORD
;
3310 else if (letter
== 'D')
3313 fprintf (file
, "%s", reg_names
[regnum
]);
3316 else if (code
== MEM
)
3317 output_address (XEXP (op
, 0));
3319 else if (code
== CONST_DOUBLE
)
3321 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
3322 union { double d
; int i
[2]; } u
;
3323 u
.i
[0] = CONST_DOUBLE_LOW (op
);
3324 u
.i
[1] = CONST_DOUBLE_HIGH (op
);
3325 if (GET_MODE (op
) == SFmode
)
3331 fprintf (file
, "%.20e", u
.d
);
3333 fatal ("CONST_DOUBLE found in cross compilation");
3337 else if ((letter
== 'x') && (GET_CODE(op
) == CONST_INT
))
3338 fprintf (file
, "0x%04x", 0xffff & (INTVAL(op
)));
3340 else if ((letter
== 'X') && (GET_CODE(op
) == CONST_INT
))
3341 fprintf (file
, "0x%08x", INTVAL(op
));
3343 else if ((letter
== 'd') && (GET_CODE(op
) == CONST_INT
))
3344 fprintf (file
, "%d", (INTVAL(op
)));
3346 else if (letter
== 'z'
3347 && (GET_CODE (op
) == CONST_INT
)
3348 && INTVAL (op
) == 0)
3349 fputs (reg_names
[GP_REG_FIRST
], file
);
3351 else if (letter
== 'd' || letter
== 'x' || letter
== 'X')
3352 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter
);
3355 output_addr_const (file
, op
);
3359 /* A C compound statement to output to stdio stream STREAM the
3360 assembler syntax for an instruction operand that is a memory
3361 reference whose address is ADDR. ADDR is an RTL expression.
3363 On some machines, the syntax for a symbolic address depends on
3364 the section that the address refers to. On these machines,
3365 define the macro `ENCODE_SECTION_INFO' to store the information
3366 into the `symbol_ref', and then check for it here. */
3369 print_operand_address (file
, addr
)
3374 error ("PRINT_OPERAND_ADDRESS, null pointer");
3377 switch (GET_CODE (addr
))
3380 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #1");
3384 if (REGNO (addr
) == ARG_POINTER_REGNUM
)
3385 abort_with_insn (addr
, "Arg pointer not eliminated.");
3387 fprintf (file
, "0(%s)", reg_names
[REGNO (addr
)]);
3392 register rtx reg
= (rtx
)0;
3393 register rtx offset
= (rtx
)0;
3394 register rtx arg0
= XEXP (addr
, 0);
3395 register rtx arg1
= XEXP (addr
, 1);
3397 if (GET_CODE (arg0
) == REG
)
3401 if (GET_CODE (offset
) == REG
)
3402 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, 2 regs");
3404 else if (GET_CODE (arg1
) == REG
)
3409 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
3411 output_addr_const (file
, addr
);
3415 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, no regs");
3417 if (!CONSTANT_P (offset
))
3418 abort_with_insn (addr
, "PRINT_OPERAND_ADDRESS, illegal insn #2");
3420 if (REGNO (reg
) == ARG_POINTER_REGNUM
)
3421 abort_with_insn (addr
, "Arg pointer not eliminated.");
3423 output_addr_const (file
, offset
);
3424 fprintf (file
, "(%s)", reg_names
[REGNO (reg
)]);
3432 output_addr_const (file
, addr
);
3438 /* If optimizing for the global pointer, keep track of all of
3439 the externs, so that at the end of the file, we can emit
3440 the appropriate .extern declaration for them, before writing
3441 out the text section. We assume that all names passed to
3442 us are in the permanent obstack, so that they will be valid
3443 at the end of the compilation.
3445 If we have -G 0, or the extern size is unknown, don't bother
3446 emitting the .externs. */
3449 mips_output_external (file
, decl
, name
)
3454 register struct extern_list
*p
;
3458 && mips_section_threshold
!= 0
3459 && ((TREE_CODE (decl
)) != FUNCTION_DECL
)
3460 && ((len
= int_size_in_bytes (TREE_TYPE (decl
))) > 0))
3462 p
= (struct extern_list
*)permalloc ((long) sizeof (struct extern_list
));
3463 p
->next
= extern_head
;
3472 /* Compute a string to use as a temporary file name. */
3478 char *base
= getenv ("TMPDIR");
3481 if (base
== (char *)0)
3484 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
3488 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
3494 len
= strlen (base
);
3495 temp_filename
= (char *) alloca (len
+ sizeof("/ccXXXXXX"));
3496 strcpy (temp_filename
, base
);
3497 if (len
> 0 && temp_filename
[len
-1] != '/')
3498 temp_filename
[len
++] = '/';
3500 strcpy (temp_filename
+ len
, "ccXXXXXX");
3501 mktemp (temp_filename
);
3503 stream
= fopen (temp_filename
, "w+");
3505 pfatal_with_name (temp_filename
);
3507 unlink (temp_filename
);
3512 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out
3513 for .file's that start within a function. If we are smuggling stabs, try to
3514 put out a MIPS ECOFF file and a stab. */
3517 mips_output_filename (stream
, name
)
3521 static int first_time
= TRUE
;
3522 char ltext_label_name
[100];
3528 current_function_file
= name
;
3529 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
3530 output_quoted_string (stream
, name
);
3531 fprintf (stream
, "\n");
3532 /* This tells mips-tfile that stabs will follow. */
3533 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3534 fprintf (stream
, "\t#@stabs\n");
3537 else if (write_symbols
== DBX_DEBUG
)
3539 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
3540 fprintf (stream
, "%s ", ASM_STABS_OP
);
3541 output_quoted_string (stream
, name
);
3542 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
3545 else if (name
!= current_function_file
3546 && strcmp (name
, current_function_file
) != 0)
3548 if (inside_function
&& !TARGET_GAS
)
3550 if (!file_in_function_warning
)
3552 file_in_function_warning
= TRUE
;
3553 ignore_line_number
= TRUE
;
3554 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line");
3557 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
3563 current_function_file
= name
;
3564 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
3566 output_quoted_string (stream
, name
);
3567 fprintf (stream
, "\n");
3572 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
3573 as well as a .loc, since it is possible that MIPS ECOFF might not be
3574 able to represent the location for inlines that come from a different
3578 mips_output_lineno (stream
, line
)
3582 if (write_symbols
== DBX_DEBUG
)
3585 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3586 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
3591 fprintf (stream
, "\n\t%s.loc\t%d %d\n",
3592 (ignore_line_number
) ? "#" : "",
3593 num_source_filenames
, line
);
3595 LABEL_AFTER_LOC (stream
);
3600 /* If defined, a C statement to be executed just prior to the
3601 output of assembler code for INSN, to modify the extracted
3602 operands so they will be output differently.
3604 Here the argument OPVEC is the vector containing the operands
3605 extracted from INSN, and NOPERANDS is the number of elements of
3606 the vector which contain meaningful data for this insn. The
3607 contents of this vector are what will be used to convert the
3608 insn template into assembler code, so you can change the
3609 assembler output by changing the contents of the vector.
3611 We use it to check if the current insn needs a nop in front of it
3612 because of load delays, and also to update the delay slot
3616 final_prescan_insn (insn
, opvec
, noperands
)
3621 if (dslots_number_nops
> 0)
3623 rtx pattern
= PATTERN (insn
);
3624 int length
= get_attr_length (insn
);
3626 /* Do we need to emit a NOP? */
3628 || (mips_load_reg
!= (rtx
)0 && reg_mentioned_p (mips_load_reg
, pattern
))
3629 || (mips_load_reg2
!= (rtx
)0 && reg_mentioned_p (mips_load_reg2
, pattern
))
3630 || (mips_load_reg3
!= (rtx
)0 && reg_mentioned_p (mips_load_reg3
, pattern
))
3631 || (mips_load_reg4
!= (rtx
)0 && reg_mentioned_p (mips_load_reg4
, pattern
)))
3632 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
3635 dslots_load_filled
++;
3637 while (--dslots_number_nops
> 0)
3638 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
3640 mips_load_reg
= (rtx
)0;
3641 mips_load_reg2
= (rtx
)0;
3642 mips_load_reg3
= (rtx
)0;
3643 mips_load_reg4
= (rtx
)0;
3645 if (set_noreorder
&& --set_noreorder
== 0)
3646 fputs ("\t.set\treorder\n", asm_out_file
);
3651 enum rtx_code code
= GET_CODE (insn
);
3652 if (code
== JUMP_INSN
|| code
== CALL_INSN
)
3653 dslots_jump_total
++;
3658 /* Output at beginning of assembler file.
3659 If we are optimizing to use the global pointer, create a temporary
3660 file to hold all of the text stuff, and write it out to the end.
3661 This is needed because the MIPS assembler is evidently one pass,
3662 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata
3663 declaration when the code is processed, it generates a two
3664 instruction sequence. */
3667 mips_asm_file_start (stream
)
3670 ASM_OUTPUT_SOURCE_FILENAME (stream
, main_input_filename
);
3672 /* Versions of the MIPS assembler before 2.20 generate errors
3673 if a branch inside of a .set noreorder section jumps to a
3674 label outside of the .set noreorder section. Revision 2.20
3675 just set nobopt silently rather than fixing the bug. */
3677 if (TARGET_MIPS_AS
&& optimize
&& flag_delayed_branch
)
3678 fprintf (stream
, "\t.set\tnobopt\n");
3680 /* Generate the pseudo ops that System V.4 wants. */
3681 #ifndef ABICALLS_ASM_OP
3682 #define ABICALLS_ASM_OP ".abicalls"
3684 if (TARGET_ABICALLS
)
3685 /* ??? but do not want this (or want pic0) if -non-shared? */
3686 fprintf (stream
, "\t%s\n", ABICALLS_ASM_OP
);
3690 asm_out_data_file
= stream
;
3691 asm_out_text_file
= make_temp_file ();
3694 asm_out_data_file
= asm_out_text_file
= stream
;
3696 if (TARGET_NAME_REGS
)
3697 fprintf (asm_out_file
, "#include <regdef.h>\n");
3699 print_options (stream
);
3703 /* If we are optimizing the global pointer, emit the text section now
3704 and any small externs which did not have .comm, etc that are
3705 needed. Also, give a warning if the data area is more than 32K and
3706 -pic because 3 instructions are needed to reference the data
3710 mips_asm_file_end (file
)
3715 struct extern_list
*p
;
3719 HALF_PIC_FINISH (file
);
3726 for (p
= extern_head
; p
!= 0; p
= p
->next
)
3728 name_tree
= get_identifier (p
->name
);
3730 /* Positively ensure only one .extern for any given symbol. */
3731 if (! TREE_ASM_WRITTEN (name_tree
))
3733 TREE_ASM_WRITTEN (name_tree
) = 1;
3734 fputs ("\t.extern\t", file
);
3735 assemble_name (file
, p
->name
);
3736 fprintf (file
, ", %d\n", p
->size
);
3740 fprintf (file
, "\n\t.text\n");
3741 rewind (asm_out_text_file
);
3742 if (ferror (asm_out_text_file
))
3743 fatal_io_error (temp_filename
);
3745 while ((len
= fread (buffer
, 1, sizeof (buffer
), asm_out_text_file
)) > 0)
3746 if (fwrite (buffer
, 1, len
, file
) != len
)
3747 pfatal_with_name (asm_file_name
);
3750 pfatal_with_name (temp_filename
);
3752 if (fclose (asm_out_text_file
) != 0)
3753 pfatal_with_name (temp_filename
);
3758 /* Emit either a label, .comm, or .lcomm directive, and mark
3759 that the symbol is used, so that we don't emit an .extern
3760 for it in mips_asm_file_end. */
3763 mips_declare_object (stream
, name
, init_string
, final_string
, size
)
3770 fputs (init_string
, stream
); /* "", "\t.comm\t", or "\t.lcomm\t" */
3771 assemble_name (stream
, name
);
3772 fprintf (stream
, final_string
, size
); /* ":\n", ",%u\n", ",%u\n" */
3774 if (TARGET_GP_OPT
&& mips_section_threshold
!= 0)
3776 tree name_tree
= get_identifier (name
);
3777 TREE_ASM_WRITTEN (name_tree
) = 1;
3782 /* Output a double precision value to the assembler. If both the
3783 host and target are IEEE, emit the values in hex. */
3786 mips_output_double (stream
, value
)
3788 REAL_VALUE_TYPE value
;
3790 #ifdef REAL_VALUE_TO_TARGET_DOUBLE
3792 REAL_VALUE_TO_TARGET_DOUBLE (value
, value_long
);
3794 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n",
3795 value_long
[0], value
, value_long
[1]);
3797 fprintf (stream
, "\t.double\t%.20g\n", value
);
3802 /* Output a single precision value to the assembler. If both the
3803 host and target are IEEE, emit the values in hex. */
3806 mips_output_float (stream
, value
)
3808 REAL_VALUE_TYPE value
;
3810 #ifdef REAL_VALUE_TO_TARGET_SINGLE
3812 REAL_VALUE_TO_TARGET_SINGLE (value
, value_long
);
3814 fprintf (stream
, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long
, value
);
3816 fprintf (stream
, "\t.float\t%.12g\n", value
);
3821 /* Return TRUE if any register used in the epilogue is used. This to insure
3822 any insn put into the epilogue delay slots is safe. */
3825 epilogue_reg_mentioned_p (insn
)
3830 register enum rtx_code code
;
3836 if (GET_CODE (insn
) == LABEL_REF
)
3839 code
= GET_CODE (insn
);
3843 regno
= REGNO (insn
);
3844 if (regno
== STACK_POINTER_REGNUM
)
3847 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
3850 if (!call_used_regs
[regno
])
3853 if (regno
!= MIPS_TEMP1_REGNUM
&& regno
!= MIPS_TEMP2_REGNUM
)
3856 if (!current_frame_info
.initialized
)
3857 compute_frame_size (get_frame_size ());
3859 return (current_frame_info
.total_size
>= 32768);
3869 fmt
= GET_RTX_FORMAT (code
);
3870 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3875 for (j
= XVECLEN (insn
, i
) - 1; j
>= 0; j
--)
3876 if (epilogue_reg_mentioned_p (XVECEXP (insn
, i
, j
)))
3879 else if (fmt
[i
] == 'e' && epilogue_reg_mentioned_p (XEXP (insn
, i
)))
3887 /* Return the bytes needed to compute the frame pointer from the current
3890 Mips stack frames look like:
3892 Before call After call
3893 +-----------------------+ +-----------------------+
3896 | caller's temps. | | caller's temps. |
3898 +-----------------------+ +-----------------------+
3900 | arguments on stack. | | arguments on stack. |
3902 +-----------------------+ +-----------------------+
3903 | 4 words to save | | 4 words to save |
3904 | arguments passed | | arguments passed |
3905 | in registers, even | | in registers, even |
3906 SP->| if not passed. | VFP->| if not passed. |
3907 +-----------------------+ +-----------------------+
3909 | fp register save |
3911 +-----------------------+
3913 | gp register save |
3915 +-----------------------+
3919 +-----------------------+
3921 | alloca allocations |
3923 +-----------------------+
3925 | GP save for V.4 abi |
3927 +-----------------------+
3929 | arguments on stack |
3931 +-----------------------+
3933 | arguments passed |
3934 | in registers, even |
3935 low SP->| if not passed. |
3936 memory +-----------------------+
3941 compute_frame_size (size
)
3942 int size
; /* # of var. bytes allocated */
3945 long total_size
; /* # bytes that the entire frame takes up */
3946 long var_size
; /* # bytes that variables take up */
3947 long args_size
; /* # bytes that outgoing arguments take up */
3948 long extra_size
; /* # extra bytes */
3949 long gp_reg_rounded
; /* # bytes needed to store gp after rounding */
3950 long gp_reg_size
; /* # bytes needed to store gp regs */
3951 long fp_reg_size
; /* # bytes needed to store fp regs */
3952 long mask
; /* mask of saved gp registers */
3953 long fmask
; /* mask of saved fp registers */
3954 int fp_inc
; /* 1 or 2 depending on the size of fp regs */
3955 long fp_bits
; /* bitmask to use for each fp register */
3961 extra_size
= MIPS_STACK_ALIGN (((TARGET_ABICALLS
) ? UNITS_PER_WORD
: 0));
3962 var_size
= MIPS_STACK_ALIGN (size
);
3963 args_size
= MIPS_STACK_ALIGN (current_function_outgoing_args_size
);
3965 /* The MIPS 3.0 linker does not like functions that dynamically
3966 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
3967 looks like we are trying to create a second frame pointer to the
3968 function, so allocate some stack space to make it happy. */
3970 if (args_size
== 0 && current_function_calls_alloca
)
3971 args_size
= 4*UNITS_PER_WORD
;
3973 total_size
= var_size
+ args_size
+ extra_size
;
3975 /* Calculate space needed for gp registers. */
3976 for (regno
= GP_REG_FIRST
; regno
<= GP_REG_LAST
; regno
++)
3978 if (MUST_SAVE_REGISTER (regno
))
3980 gp_reg_size
+= UNITS_PER_WORD
;
3981 mask
|= 1L << (regno
- GP_REG_FIRST
);
3985 /* Calculate space needed for fp registers. */
3997 for (regno
= FP_REG_FIRST
; regno
<= FP_REG_LAST
; regno
+= fp_inc
)
3999 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
4001 fp_reg_size
+= 2*UNITS_PER_WORD
;
4002 fmask
|= fp_bits
<< (regno
- FP_REG_FIRST
);
4006 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
4007 total_size
+= gp_reg_rounded
+ fp_reg_size
;
4009 if (total_size
== extra_size
)
4010 total_size
= extra_size
= 0;
4011 else if (TARGET_ABICALLS
)
4013 /* Add the context-pointer to the saved registers. */
4014 gp_reg_size
+= UNITS_PER_WORD
;
4015 mask
|= 1L << (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
);
4016 total_size
-= gp_reg_rounded
;
4017 gp_reg_rounded
= MIPS_STACK_ALIGN (gp_reg_size
);
4018 total_size
+= gp_reg_rounded
;
4021 /* Save other computed information. */
4022 current_frame_info
.total_size
= total_size
;
4023 current_frame_info
.var_size
= var_size
;
4024 current_frame_info
.args_size
= args_size
;
4025 current_frame_info
.extra_size
= extra_size
;
4026 current_frame_info
.gp_reg_size
= gp_reg_size
;
4027 current_frame_info
.fp_reg_size
= fp_reg_size
;
4028 current_frame_info
.mask
= mask
;
4029 current_frame_info
.fmask
= fmask
;
4030 current_frame_info
.initialized
= reload_completed
;
4031 current_frame_info
.num_gp
= gp_reg_size
/ UNITS_PER_WORD
;
4032 current_frame_info
.num_fp
= fp_reg_size
/ (2*UNITS_PER_WORD
);
4036 unsigned long offset
= args_size
+ extra_size
+ var_size
4037 + gp_reg_size
- UNITS_PER_WORD
;
4038 current_frame_info
.gp_sp_offset
= offset
;
4039 current_frame_info
.gp_save_offset
= offset
- total_size
;
4043 current_frame_info
.gp_sp_offset
= 0;
4044 current_frame_info
.gp_save_offset
= 0;
4050 unsigned long offset
= args_size
+ extra_size
+ var_size
4051 + gp_reg_rounded
+ fp_reg_size
- 2*UNITS_PER_WORD
;
4052 current_frame_info
.fp_sp_offset
= offset
;
4053 current_frame_info
.fp_save_offset
= offset
- total_size
+ UNITS_PER_WORD
;
4057 current_frame_info
.fp_sp_offset
= 0;
4058 current_frame_info
.fp_save_offset
= 0;
4061 /* Ok, we're done. */
4066 /* Common code to emit the insns (or to write the instructions to a file)
4067 to save/restore registers.
4069 Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg)
4070 is not modified within save_restore_insns. */
4072 #define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0)
4075 save_restore_insns (store_p
, large_reg
, large_offset
, file
)
4076 int store_p
; /* true if this is prologue */
4077 rtx large_reg
; /* register holding large offset constant or NULL */
4078 long large_offset
; /* large constant offset value */
4079 FILE *file
; /* file to write instructions to instead of making RTL */
4081 long mask
= current_frame_info
.mask
;
4082 long fmask
= current_frame_info
.fmask
;
4090 if (frame_pointer_needed
&& !BITSET_P (mask
, FRAME_POINTER_REGNUM
- GP_REG_FIRST
))
4093 if (mask
== 0 && fmask
== 0)
4096 /* Save registers starting from high to low. The debuggers prefer
4097 at least the return register be stored at func+4, and also it
4098 allows us not to need a nop in the epilog if at least one
4099 register is reloaded in addition to return address. */
4101 /* Save GP registers if needed. */
4104 /* Pick which pointer to use as a base register. For small
4105 frames, just use the stack pointer. Otherwise, use a
4106 temporary register. Save 2 cycles if the save area is near
4107 the end of a large frame, by reusing the constant created in
4108 the prologue/epilogue to adjust the stack frame. */
4110 gp_offset
= current_frame_info
.gp_sp_offset
;
4111 end_offset
= gp_offset
- (current_frame_info
.gp_reg_size
- UNITS_PER_WORD
);
4113 if (gp_offset
< 0 || end_offset
< 0)
4114 fatal ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
4115 gp_offset
, end_offset
);
4117 else if (gp_offset
< 32768)
4119 base_reg_rtx
= stack_pointer_rtx
;
4123 else if (large_reg
!= (rtx
)0
4124 && (((unsigned long)(large_offset
- gp_offset
)) < 32768)
4125 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4127 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4128 base_offset
= large_offset
;
4129 if (file
== (FILE *)0)
4130 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4132 fprintf (file
, "\taddu\t%s,%s,%s\n",
4133 reg_names
[MIPS_TEMP2_REGNUM
],
4134 reg_names
[REGNO (large_reg
)],
4135 reg_names
[STACK_POINTER_REGNUM
]);
4140 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4141 base_offset
= gp_offset
;
4142 if (file
== (FILE *)0)
4144 emit_move_insn (base_reg_rtx
, GEN_INT (gp_offset
));
4145 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4148 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n",
4149 reg_names
[MIPS_TEMP2_REGNUM
],
4152 reg_names
[MIPS_TEMP2_REGNUM
],
4153 reg_names
[MIPS_TEMP2_REGNUM
],
4154 reg_names
[STACK_POINTER_REGNUM
]);
4157 for (regno
= GP_REG_LAST
; regno
>= GP_REG_FIRST
; regno
--)
4159 if (BITSET_P (mask
, regno
- GP_REG_FIRST
))
4161 if (file
== (FILE *)0)
4163 rtx reg_rtx
= gen_rtx (REG
, Pmode
, regno
);
4164 rtx mem_rtx
= gen_rtx (MEM
, Pmode
,
4165 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4166 GEN_INT (gp_offset
- base_offset
)));
4169 emit_move_insn (mem_rtx
, reg_rtx
);
4170 else if (!TARGET_ABICALLS
4171 || regno
!= (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
))
4172 emit_move_insn (reg_rtx
, mem_rtx
);
4176 if (store_p
|| !TARGET_ABICALLS
4177 || regno
!= (PIC_OFFSET_TABLE_REGNUM
- GP_REG_FIRST
))
4178 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4179 (store_p
) ? "sw" : "lw",
4181 gp_offset
- base_offset
,
4182 reg_names
[REGNO(base_reg_rtx
)]);
4185 gp_offset
-= UNITS_PER_WORD
;
4191 base_reg_rtx
= (rtx
)0; /* Make sure these are initialzed */
4195 /* Save floating point registers if needed. */
4198 int fp_inc
= (TARGET_FLOAT64
) ? 1 : 2;
4200 /* Pick which pointer to use as a base register. */
4201 fp_offset
= current_frame_info
.fp_sp_offset
;
4202 end_offset
= fp_offset
- (current_frame_info
.fp_reg_size
- 2*UNITS_PER_WORD
);
4204 if (fp_offset
< 0 || end_offset
< 0)
4205 fatal ("fp_offset (%ld) or end_offset (%ld) is less than zero.",
4206 fp_offset
, end_offset
);
4208 else if (fp_offset
< 32768)
4210 base_reg_rtx
= stack_pointer_rtx
;
4214 else if (base_reg_rtx
!= (rtx
)0
4215 && (((unsigned long)(base_offset
- fp_offset
)) < 32768)
4216 && (((unsigned long)(base_offset
- end_offset
)) < 32768))
4218 ; /* already set up for gp registers above */
4221 else if (large_reg
!= (rtx
)0
4222 && (((unsigned long)(large_offset
- fp_offset
)) < 32768)
4223 && (((unsigned long)(large_offset
- end_offset
)) < 32768))
4225 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4226 base_offset
= large_offset
;
4227 if (file
== (FILE *)0)
4228 emit_insn (gen_addsi3 (base_reg_rtx
, large_reg
, stack_pointer_rtx
));
4230 fprintf (file
, "\taddu\t%s,%s,%s\n",
4231 reg_names
[MIPS_TEMP2_REGNUM
],
4232 reg_names
[REGNO (large_reg
)],
4233 reg_names
[STACK_POINTER_REGNUM
]);
4238 base_reg_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP2_REGNUM
);
4239 base_offset
= fp_offset
;
4240 if (file
== (FILE *)0)
4242 emit_move_insn (base_reg_rtx
, GEN_INT (fp_offset
));
4243 emit_insn (gen_addsi3 (base_reg_rtx
, base_reg_rtx
, stack_pointer_rtx
));
4246 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n",
4247 reg_names
[MIPS_TEMP2_REGNUM
],
4250 reg_names
[MIPS_TEMP2_REGNUM
],
4251 reg_names
[MIPS_TEMP2_REGNUM
],
4252 reg_names
[STACK_POINTER_REGNUM
]);
4255 for (regno
= FP_REG_LAST
-1; regno
>= FP_REG_FIRST
; regno
-= fp_inc
)
4257 if (BITSET_P (fmask
, regno
- FP_REG_FIRST
))
4259 if (file
== (FILE *)0)
4261 rtx reg_rtx
= gen_rtx (REG
, DFmode
, regno
);
4262 rtx mem_rtx
= gen_rtx (MEM
, DFmode
,
4263 gen_rtx (PLUS
, Pmode
, base_reg_rtx
,
4264 GEN_INT (fp_offset
- base_offset
)));
4267 emit_move_insn (mem_rtx
, reg_rtx
);
4269 emit_move_insn (reg_rtx
, mem_rtx
);
4272 fprintf (file
, "\t%s\t%s,%ld(%s)\n",
4273 (store_p
) ? "s.d" : "l.d",
4275 fp_offset
- base_offset
,
4276 reg_names
[REGNO(base_reg_rtx
)]);
4279 fp_offset
-= 2*UNITS_PER_WORD
;
4286 /* Set up the stack and frame (if desired) for the function. */
4289 function_prologue (file
, size
)
4293 long tsize
= current_frame_info
.total_size
;
4295 ASM_OUTPUT_SOURCE_FILENAME (file
, DECL_SOURCE_FILE (current_function_decl
));
4297 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
4298 ASM_OUTPUT_SOURCE_LINE (file
, DECL_SOURCE_LINE (current_function_decl
));
4300 inside_function
= 1;
4301 fputs ("\t.ent\t", file
);
4302 assemble_name (file
, current_function_name
);
4305 assemble_name (file
, current_function_name
);
4306 fputs (":\n", file
);
4308 fprintf (file
, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args= %d, extra= %d\n",
4309 reg_names
[ (frame_pointer_needed
) ? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
],
4311 reg_names
[31 + GP_REG_FIRST
],
4312 current_frame_info
.var_size
,
4313 current_frame_info
.num_gp
,
4314 current_frame_info
.num_fp
,
4315 current_function_outgoing_args_size
,
4316 current_frame_info
.extra_size
);
4318 fprintf (file
, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n",
4319 current_frame_info
.mask
,
4320 current_frame_info
.gp_save_offset
,
4321 current_frame_info
.fmask
,
4322 current_frame_info
.fp_save_offset
);
4324 if (TARGET_ABICALLS
)
4326 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4328 fprintf (file
, "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
4329 reg_names
[PIC_FUNCTION_ADDR_REGNUM
]);
4332 fprintf (file
, "\tsubu\t%s,%s,%d\n", sp_str
, sp_str
, tsize
);
4333 fprintf (file
, "\t.cprestore %d\n", current_frame_info
.args_size
);
4339 /* Expand the prologue into a bunch of separate insns. */
4342 mips_expand_prologue ()
4346 rtx tmp_rtx
= (rtx
)0;
4347 char *arg_name
= (char *)0;
4348 tree fndecl
= current_function_decl
;
4349 tree fntype
= TREE_TYPE (fndecl
);
4350 tree fnargs
= (TREE_CODE (fntype
) != METHOD_TYPE
)
4351 ? DECL_ARGUMENTS (fndecl
)
4357 CUMULATIVE_ARGS args_so_far
;
4359 /* If struct value address is treated as the first argument, make it so. */
4360 if (aggregate_value_p (DECL_RESULT (fndecl
))
4361 && ! current_function_returns_pcc_struct
4362 && struct_value_incoming_rtx
== 0)
4364 tree type
= build_pointer_type (fntype
);
4365 tree function_result_decl
= build_decl (PARM_DECL
, NULL_TREE
, type
);
4366 DECL_ARG_TYPE (function_result_decl
) = type
;
4367 TREE_CHAIN (function_result_decl
) = fnargs
;
4368 fnargs
= function_result_decl
;
4371 /* Determine the last argument, and get its name. */
4373 INIT_CUMULATIVE_ARGS (args_so_far
, fntype
, (rtx
)0);
4374 regno
= GP_ARG_FIRST
;
4376 for (cur_arg
= fnargs
; cur_arg
!= (tree
)0; cur_arg
= next_arg
)
4378 tree type
= DECL_ARG_TYPE (cur_arg
);
4379 enum machine_mode passed_mode
= TYPE_MODE (type
);
4380 rtx entry_parm
= FUNCTION_ARG (args_so_far
,
4382 DECL_ARG_TYPE (cur_arg
),
4389 /* passed in a register, so will get homed automatically */
4390 if (GET_MODE (entry_parm
) == BLKmode
)
4391 words
= (int_size_in_bytes (type
) + 3) / 4;
4393 words
= (GET_MODE_SIZE (GET_MODE (entry_parm
)) + 3) / 4;
4395 regno
= REGNO (entry_parm
) + words
- 1;
4399 regno
= GP_ARG_LAST
+1;
4403 FUNCTION_ARG_ADVANCE (args_so_far
,
4405 DECL_ARG_TYPE (cur_arg
),
4408 next_arg
= TREE_CHAIN (cur_arg
);
4409 if (next_arg
== (tree
)0)
4411 if (DECL_NAME (cur_arg
))
4412 arg_name
= IDENTIFIER_POINTER (DECL_NAME (cur_arg
));
4418 /* In order to pass small structures by value in registers
4419 compatibly with the MIPS compiler, we need to shift the value
4420 into the high part of the register. Function_arg has encoded a
4421 PARALLEL rtx, holding a vector of adjustments to be made as the
4422 next_arg_reg variable, so we split up the insns, and emit them
4425 next_arg_reg
= FUNCTION_ARG (args_so_far
, VOIDmode
, void_type_node
, 1);
4426 if (next_arg_reg
!= (rtx
)0 && GET_CODE (next_arg_reg
) == PARALLEL
)
4428 rtvec adjust
= XVEC (next_arg_reg
, 0);
4429 int num
= GET_NUM_ELEM (adjust
);
4431 for (i
= 0; i
< num
; i
++)
4433 rtx pattern
= RTVEC_ELT (adjust
, i
);
4434 if (GET_CODE (pattern
) != SET
4435 || GET_CODE (SET_SRC (pattern
)) != ASHIFT
)
4436 abort_with_insn (pattern
, "Insn is not a shift");
4438 PUT_CODE (SET_SRC (pattern
), ASHIFTRT
);
4439 emit_insn (pattern
);
4443 tsize
= compute_frame_size (get_frame_size ());
4445 /* If this function is a varargs function, store any registers that
4446 would normally hold arguments ($4 - $7) on the stack. */
4447 if ((TYPE_ARG_TYPES (fntype
) != 0
4448 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
))) != void_type_node
))
4449 || (arg_name
!= (char *)0
4450 && ((arg_name
[0] == '_' && strcmp (arg_name
, "__builtin_va_alist") == 0)
4451 || (arg_name
[0] == 'v' && strcmp (arg_name
, "va_alist") == 0))))
4453 int offset
= (regno
- GP_ARG_FIRST
) * UNITS_PER_WORD
;
4454 rtx ptr
= stack_pointer_rtx
;
4456 /* If we are doing svr4-abi, sp has already been decremented by tsize. */
4457 if (TARGET_ABICALLS
)
4460 for (; regno
<= GP_ARG_LAST
; regno
++)
4463 ptr
= gen_rtx (PLUS
, Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
4464 emit_move_insn (gen_rtx (MEM
, Pmode
, ptr
),
4465 gen_rtx (REG
, Pmode
, regno
));
4466 offset
+= UNITS_PER_WORD
;
4472 rtx tsize_rtx
= GEN_INT (tsize
);
4474 /* If we are doing svr4-abi, sp move is done by function_prologue. */
4475 if (!TARGET_ABICALLS
)
4479 tmp_rtx
= gen_rtx (REG
, SImode
, MIPS_TEMP1_REGNUM
);
4480 emit_move_insn (tmp_rtx
, tsize_rtx
);
4481 tsize_rtx
= tmp_rtx
;
4484 emit_insn (gen_subsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
4488 save_restore_insns (TRUE
, tmp_rtx
, tsize
, (FILE *)0);
4490 if (frame_pointer_needed
)
4491 emit_insn (gen_movsi (frame_pointer_rtx
, stack_pointer_rtx
));
4494 /* If we are profiling, make sure no instructions are scheduled before
4495 the call to mcount. */
4497 if (profile_flag
|| profile_block_flag
)
4498 emit_insn (gen_blockage ());
4502 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */
4504 #define RA_MASK ((long) 0x80000000) /* 1 << 31 */
4507 function_epilogue (file
, size
)
4512 char *sp_str
= reg_names
[STACK_POINTER_REGNUM
];
4513 char *t1_str
= reg_names
[MIPS_TEMP1_REGNUM
];
4514 rtx epilogue_delay
= current_function_epilogue_delay_list
;
4515 int noreorder
= !TARGET_MIPS_AS
|| (epilogue_delay
!= 0);
4516 int noepilogue
= FALSE
;
4517 int load_nop
= FALSE
;
4519 rtx tmp_rtx
= (rtx
)0;
4523 /* The epilogue does not depend on any registers, but the stack
4524 registers, so we assume that if we have 1 pending nop, it can be
4525 ignored, and 2 it must be filled (2 nops occur for integer
4526 multiply and divide). */
4528 if (dslots_number_nops
> 0)
4530 if (dslots_number_nops
== 1)
4532 dslots_number_nops
= 0;
4533 dslots_load_filled
++;
4537 while (--dslots_number_nops
> 0)
4538 fputs ((set_noreorder
) ? "\tnop\n" : "\t#nop\n", asm_out_file
);
4541 if (set_noreorder
> 0 && --set_noreorder
== 0)
4542 fputs ("\t.set\treorder\n", file
);
4548 fputs ("\t.set\tat\n", file
);
4549 error ("internal gcc error: .set noat left on in epilogue");
4552 if (set_nomacro
!= 0)
4555 fputs ("\t.set\tmacro\n", file
);
4556 error ("internal gcc error: .set nomacro left on in epilogue");
4559 if (set_noreorder
!= 0)
4562 fputs ("\t.set\treorder\n", file
);
4563 error ("internal gcc error: .set noreorder left on in epilogue");
4566 if (set_volatile
!= 0)
4569 fprintf (file
, "\t#.set\tnovolatile\n", (TARGET_MIPS_AS
) ? "" : "#");
4570 error ("internal gcc error: .set volatile left on in epilogue");
4573 size
= MIPS_STACK_ALIGN (size
);
4574 tsize
= (!current_frame_info
.initialized
)
4575 ? compute_frame_size (size
)
4576 : current_frame_info
.total_size
;
4578 if (tsize
== 0 && epilogue_delay
== 0)
4580 rtx insn
= get_last_insn ();
4582 /* If the last insn was a BARRIER, we don't have to write any code
4583 because a jump (aka return) was put there. */
4584 if (GET_CODE (insn
) == NOTE
)
4585 insn
= prev_nonnote_insn (insn
);
4586 if (insn
&& GET_CODE (insn
) == BARRIER
)
4594 /* In the reload sequence, we don't need to fill the load delay
4595 slots for most of the loads, also see if we can fill the final
4596 delay slot if not otherwise filled by the reload sequence. */
4599 fprintf (file
, "\t.set\tnoreorder\n");
4603 fprintf (file
, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str
, (long)tsize
, (long)tsize
);
4604 tmp_rtx
= gen_rtx (REG
, Pmode
, MIPS_TEMP1_REGNUM
);
4607 if (frame_pointer_needed
)
4608 fprintf (file
, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
4609 sp_str
, reg_names
[FRAME_POINTER_REGNUM
]);
4611 save_restore_insns (FALSE
, tmp_rtx
, tsize
, file
);
4613 load_only_r31
= (current_frame_info
.mask
== RA_MASK
4614 && current_frame_info
.fmask
== 0);
4618 /* If the only register saved is the return address, we need a
4619 nop, unless we have an instruction to put into it. Otherwise
4620 we don't since reloading multiple registers doesn't reference
4621 the register being loaded. */
4626 final_scan_insn (XEXP (epilogue_delay
, 0),
4630 1); /* nopeepholes */
4633 fprintf (file
, "\tnop\n");
4638 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
4641 fprintf (file
, "\taddu\t%s,%s,%s\n", sp_str
, sp_str
, t1_str
);
4644 fprintf (file
, "\taddu\t%s,%s,%d\n", sp_str
, sp_str
, tsize
);
4646 else if (!load_only_r31
&& epilogue_delay
!= 0)
4647 final_scan_insn (XEXP (epilogue_delay
, 0),
4651 1); /* nopeepholes */
4653 fprintf (file
, "\t.set\treorder\n");
4659 fprintf (file
, "\taddu\t%s,%s,%s\n", sp_str
, sp_str
, t1_str
);
4662 fprintf (file
, "\taddu\t%s,%s,%d\n", sp_str
, sp_str
, tsize
);
4664 fprintf (file
, "\tj\t%s\n", reg_names
[GP_REG_FIRST
+ 31]);
4668 fputs ("\t.end\t", file
);
4669 assemble_name (file
, current_function_name
);
4674 int num_gp_regs
= current_frame_info
.gp_reg_size
/ 4;
4675 int num_fp_regs
= current_frame_info
.fp_reg_size
/ 8;
4676 int num_regs
= num_gp_regs
+ num_fp_regs
;
4677 char *name
= current_function_name
;
4682 dslots_load_total
+= num_regs
;
4685 dslots_jump_total
++;
4689 dslots_load_filled
+= num_regs
;
4691 /* If the only register saved is the return register, we
4692 can't fill this register's delay slot. */
4694 if (load_only_r31
&& epilogue_delay
== 0)
4695 dslots_load_filled
--;
4697 if (tsize
> 0 || (!load_only_r31
&& epilogue_delay
!= 0))
4698 dslots_jump_filled
++;
4702 "%-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",
4704 (frame_pointer_needed
) ? 'y' : 'n',
4705 ((current_frame_info
.mask
& RA_MASK
) != 0) ? 'n' : 'y',
4706 (current_function_calls_alloca
) ? 'y' : 'n',
4707 (current_function_calls_setjmp
) ? 'y' : 'n',
4708 (long)current_frame_info
.total_size
,
4709 (long)current_function_outgoing_args_size
,
4710 num_gp_regs
, num_fp_regs
,
4711 dslots_load_total
, dslots_load_filled
,
4712 dslots_jump_total
, dslots_jump_filled
,
4713 num_refs
[0], num_refs
[1], num_refs
[2]);
4715 if (HALF_PIC_NUMBER_PTRS
> prev_half_pic_ptrs
)
4717 fprintf (stderr
, " half-pic=%3d", HALF_PIC_NUMBER_PTRS
- prev_half_pic_ptrs
);
4718 prev_half_pic_ptrs
= HALF_PIC_NUMBER_PTRS
;
4721 if (HALF_PIC_NUMBER_REFS
> prev_half_pic_refs
)
4723 fprintf (stderr
, " pic-ref=%3d", HALF_PIC_NUMBER_REFS
- prev_half_pic_refs
);
4724 prev_half_pic_refs
= HALF_PIC_NUMBER_REFS
;
4727 fputc ('\n', stderr
);
4730 /* Reset state info for each function. */
4731 inside_function
= FALSE
;
4732 ignore_line_number
= FALSE
;
4733 dslots_load_total
= 0;
4734 dslots_jump_total
= 0;
4735 dslots_load_filled
= 0;
4736 dslots_jump_filled
= 0;
4740 mips_load_reg
= (rtx
)0;
4741 mips_load_reg2
= (rtx
)0;
4742 current_frame_info
= zero_frame_info
;
4744 /* Restore the output file if optimizing the GP (optimizing the GP causes
4745 the text to be diverted to a tempfile, so that data decls come before
4746 references to the data). */
4749 asm_out_file
= asm_out_data_file
;
4753 /* Expand the epilogue into a bunch of separate insns. */
4756 mips_expand_epilogue ()
4758 long tsize
= current_frame_info
.total_size
;
4759 rtx tsize_rtx
= GEN_INT (tsize
);
4760 rtx tmp_rtx
= (rtx
)0;
4764 tmp_rtx
= gen_rtx (REG
, SImode
, MIPS_TEMP1_REGNUM
);
4765 emit_move_insn (tmp_rtx
, tsize_rtx
);
4766 tsize_rtx
= tmp_rtx
;
4771 if (frame_pointer_needed
)
4772 emit_insn (gen_movsi (stack_pointer_rtx
, frame_pointer_rtx
));
4774 save_restore_insns (FALSE
, tmp_rtx
, tsize
, (FILE *)0);
4776 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
, tsize_rtx
));
4779 emit_jump_insn (gen_return_internal (gen_rtx (REG
, Pmode
, GP_REG_FIRST
+31)));
4783 /* Define the number of delay slots needed for the function epilogue.
4785 On the mips, we need a slot if either no stack has been allocated,
4786 or the only register saved is the return register. */
4789 mips_epilogue_delay_slots ()
4791 if (!current_frame_info
.initialized
)
4792 (void) compute_frame_size (get_frame_size ());
4794 if (current_frame_info
.total_size
== 0)
4797 if (current_frame_info
.mask
== RA_MASK
&& current_frame_info
.fmask
== 0)
4804 /* Return true if this function is known to have a null epilogue.
4805 This allows the optimizer to omit jumps to jumps if no stack
4809 simple_epilogue_p ()
4811 if (!reload_completed
)
4814 if (current_frame_info
.initialized
)
4815 return current_frame_info
.total_size
== 0;
4817 return (compute_frame_size (get_frame_size ())) == 0;