1 /* Output routines for GCC for ARM.
2 Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 and Martin Simmons (@harleqn.co.uk).
5 More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
41 /* The maximum number of insns skipped which will be conditionalised if
43 static int max_insns_skipped
= 5;
45 extern FILE * asm_out_file
;
46 /* Some function declarations. */
48 static HOST_WIDE_INT int_log2
PROTO ((HOST_WIDE_INT
));
49 static char *output_multi_immediate
PROTO ((rtx
*, char *, char *, int,
51 static int arm_gen_constant
PROTO ((enum rtx_code
, enum machine_mode
,
52 HOST_WIDE_INT
, rtx
, rtx
, int, int));
53 static int arm_naked_function_p
PROTO ((tree
));
54 static void init_fpa_table
PROTO ((void));
55 static enum machine_mode select_dominance_cc_mode
PROTO ((enum rtx_code
, rtx
,
57 static HOST_WIDE_INT add_constant
PROTO ((rtx
, enum machine_mode
, int *));
58 static void dump_table
PROTO ((rtx
));
59 static int fixit
PROTO ((rtx
, enum machine_mode
, int));
60 static rtx find_barrier
PROTO ((rtx
, int));
61 static int broken_move
PROTO ((rtx
));
62 static char *fp_const_from_val
PROTO ((REAL_VALUE_TYPE
*));
63 static int eliminate_lr2ip
PROTO ((rtx
*));
64 static char *shift_op
PROTO ((rtx
, HOST_WIDE_INT
*));
65 static int pattern_really_clobbers_lr
PROTO ((rtx
));
66 static int function_really_clobbers_lr
PROTO ((rtx
));
67 static void emit_multi_reg_push
PROTO ((int));
68 static void emit_sfm
PROTO ((int, int));
69 static enum arm_cond_code get_arm_condition_code
PROTO ((rtx
));
71 /* Define the information needed to generate branch insns. This is
72 stored from the compare operation. */
74 rtx arm_compare_op0
, arm_compare_op1
;
77 /* What type of floating point are we tuning for? */
78 enum floating_point_type arm_fpu
;
80 /* What type of floating point instructions are available? */
81 enum floating_point_type arm_fpu_arch
;
83 /* What program mode is the cpu running in? 26-bit mode or 32-bit mode */
84 enum prog_mode_type arm_prgmode
;
86 /* Set by the -mfp=... option */
87 char * target_fp_name
= NULL
;
89 /* Used to parse -mstructure_size_boundary command line option. */
90 char * structure_size_string
= NULL
;
91 int arm_structure_size_boundary
= 32; /* Used to be 8 */
93 /* Nonzero if this is an "M" variant of the processor. */
94 int arm_fast_multiply
= 0;
96 /* Nonzero if this chip supports the ARM Architecture 4 extensions */
99 /* Nonzero if this chip can benefit from laod scheduling. */
100 int arm_ld_sched
= 0;
102 /* Nonzero if this chip is a StrongARM. */
103 int arm_is_strong
= 0;
105 /* Nonzero if this chip is a an ARM6 or an ARM7. */
106 int arm_is_6_or_7
= 0;
108 /* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
109 must report the mode of the memory reference from PRINT_OPERAND to
110 PRINT_OPERAND_ADDRESS. */
111 enum machine_mode output_memory_reference_mode
;
113 /* Nonzero if the prologue must setup `fp'. */
114 int current_function_anonymous_args
;
116 /* The register number to be used for the PIC offset register. */
117 int arm_pic_register
= 9;
119 /* Location counter of .text segment. */
120 int arm_text_location
= 0;
122 /* Set to one if we think that lr is only saved because of subroutine calls,
123 but all of these can be `put after' return insns */
124 int lr_save_eliminated
;
126 /* Set to 1 when a return insn is output, this means that the epilogue
129 static int return_used_this_function
;
131 static int arm_constant_limit
= 3;
133 /* For an explanation of these variables, see final_prescan_insn below. */
135 enum arm_cond_code arm_current_cc
;
137 int arm_target_label
;
139 /* The condition codes of the ARM, and the inverse function. */
140 char * arm_condition_codes
[] =
142 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
143 "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
146 static enum arm_cond_code
get_arm_condition_code ();
148 #define streq(string1, string2) (strcmp (string1, string2) == 0)
150 /* Initialization code */
152 #define FL_CO_PROC 0x01 /* Has external co-processor bus */
153 #define FL_FAST_MULT 0x02 /* Fast multiply */
154 #define FL_MODE26 0x04 /* 26-bit mode support */
155 #define FL_MODE32 0x08 /* 32-bit mode support */
156 #define FL_ARCH4 0x10 /* Architecture rel 4 */
157 #define FL_THUMB 0x20 /* Thumb aware */
158 #define FL_LDSCHED 0x40 /* Load scheduling necessary */
159 #define FL_STRONG 0x80 /* StrongARM */
167 /* Not all of these give usefully different compilation alternatives,
168 but there is no simple way of generalizing them. */
169 static struct processors all_cores
[] =
173 {"arm2", FL_CO_PROC
| FL_MODE26
},
174 {"arm250", FL_CO_PROC
| FL_MODE26
},
175 {"arm3", FL_CO_PROC
| FL_MODE26
},
176 {"arm6", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
177 {"arm60", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
178 {"arm600", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
179 {"arm610", FL_MODE26
| FL_MODE32
},
180 {"arm620", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
181 {"arm7", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
182 {"arm7m", FL_CO_PROC
| FL_MODE26
| FL_MODE32
| FL_FAST_MULT
}, /* arm7m doesn't exist on its own, */
183 {"arm7d", FL_CO_PROC
| FL_MODE26
| FL_MODE32
}, /* but only with D, (and I), */
184 {"arm7dm", FL_CO_PROC
| FL_MODE26
| FL_MODE32
| FL_FAST_MULT
}, /* but those don't alter the code, */
185 {"arm7di", FL_CO_PROC
| FL_MODE26
| FL_MODE32
}, /* so arm7m is sometimes used. */
186 {"arm7dmi", FL_CO_PROC
| FL_MODE26
| FL_MODE32
| FL_FAST_MULT
},
187 {"arm70", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
188 {"arm700", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
189 {"arm700i", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
190 {"arm710", FL_MODE26
| FL_MODE32
},
191 {"arm710c", FL_MODE26
| FL_MODE32
},
192 {"arm7100", FL_MODE26
| FL_MODE32
},
193 {"arm7500", FL_MODE26
| FL_MODE32
},
194 {"arm7500fe", FL_CO_PROC
| FL_MODE26
| FL_MODE32
}, /* Doesn't really have an external co-proc, but does have embedded fpu. */
195 {"arm7tdmi", FL_CO_PROC
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_THUMB
},
196 {"arm8", FL_MODE26
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_LDSCHED
},
197 {"arm810", FL_MODE26
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_LDSCHED
},
198 {"arm9", FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_THUMB
| FL_LDSCHED
},
199 {"arm9tdmi", FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_THUMB
| FL_LDSCHED
},
200 {"strongarm", FL_MODE26
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_LDSCHED
| FL_STRONG
},
201 {"strongarm110", FL_MODE26
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_LDSCHED
| FL_STRONG
},
202 {"strongarm1100", FL_MODE26
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_LDSCHED
| FL_STRONG
},
207 static struct processors all_architectures
[] =
209 /* ARM Architectures */
211 {"armv2", FL_CO_PROC
| FL_MODE26
},
212 {"armv2a", FL_CO_PROC
| FL_MODE26
},
213 {"armv3", FL_CO_PROC
| FL_MODE26
| FL_MODE32
},
214 {"armv3m", FL_CO_PROC
| FL_MODE26
| FL_MODE32
| FL_FAST_MULT
},
215 {"armv4", FL_CO_PROC
| FL_MODE26
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
},
216 /* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
217 implementations that support it, so we will leave it out for now. */
218 {"armv4t", FL_CO_PROC
| FL_MODE32
| FL_FAST_MULT
| FL_ARCH4
| FL_THUMB
},
222 /* This is a magic stucture. The 'string' field is magically filled in
223 with a pointer to the value specified by the user on the command line
224 assuming that the user has specified such a value. */
226 struct arm_cpu_select arm_select
[] =
228 /* string name processors */
229 { NULL
, "-mcpu=", all_cores
},
230 { NULL
, "-march=", all_architectures
},
231 { NULL
, "-mtune=", all_cores
}
234 /* Fix up any incompatible options that the user has specified.
235 This has now turned into a maze. */
237 arm_override_options ()
239 unsigned int flags
= 0;
241 struct arm_cpu_select
* ptr
;
243 /* Set up the flags based on the cpu/architecture selected by the user. */
244 for (i
= sizeof (arm_select
) / sizeof (arm_select
[0]); i
--;)
246 struct arm_cpu_select
* ptr
= arm_select
+ i
;
248 if (ptr
->string
!= NULL
&& ptr
->string
[0] != '\0')
250 struct processors
* sel
;
252 for (sel
= ptr
->processors
; sel
->name
!= NULL
; sel
++)
253 if (streq (ptr
->string
, sel
->name
))
257 /* We scan the arm_select array in the order:
259 So if we have been asked to tune for, say, an ARM8,
260 but we are told that the cpu is only an ARM6, then
261 we have problems. We detect this by seeing if the
262 flags bits accumulated so far can be supported by the
263 cpu/architecture type now being parsed. If they can,
264 then OR in any new bits. If they cannot then report
266 if ((flags
& sel
->flags
) != flags
)
267 error ("switch %s%s overridden by another switch",
268 ptr
->string
, sel
->name
);
276 if (sel
->name
== NULL
)
277 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
281 /* If the user did not specify a processor, choose one for them. */
284 struct processors
* sel
;
287 if (TARGET_THUMB_INTERWORK
)
291 /* Force apcs-32 to be used for Thumb targets. */
292 target_flags
|= ARM_FLAG_APCS_32
;
302 for (sel
= all_cores
; sel
->name
!= NULL
; sel
++)
303 if ((sel
->flags
& sought
) == sought
)
309 if (sel
->name
== NULL
)
310 fatal ("Unable to select a cpu that matches command line specification");
314 /* The user did not specify any command line switches that require
315 a certain kind of CPU. Use TARGET_CPU_DEFAULT instead. */
317 static struct cpu_default
324 { TARGET_CPU_arm2
, "arm2" },
325 { TARGET_CPU_arm6
, "arm6" },
326 { TARGET_CPU_arm610
, "arm610" },
327 { TARGET_CPU_arm7m
, "arm7m" },
328 { TARGET_CPU_arm7500fe
, "arm7500fe" },
329 { TARGET_CPU_arm7tdmi
, "arm7tdmi" },
330 { TARGET_CPU_arm8
, "arm8" },
331 { TARGET_CPU_arm810
, "arm810" },
332 { TARGET_CPU_arm9
, "arm9" },
333 { TARGET_CPU_strongarm
, "strongarm" },
334 { TARGET_CPU_generic
, "arm" },
337 struct cpu_default
* def
;
339 /* Find the default. */
340 for (def
= cpu_defaults
; def
->name
; def
++)
341 if (def
->cpu
== TARGET_CPU_DEFAULT
)
344 if (def
->name
== NULL
)
347 /* Find the default CPU's flags. */
348 for (sel
= all_cores
; sel
->name
!= NULL
; sel
++)
349 if (streq (def
->name
, sel
->name
))
352 if (sel
->name
== NULL
)
359 /* Make sure that the processor choice does not conflict with any of the
360 other command line choices. */
361 if (TARGET_APCS_32
&& !(flags
& FL_MODE32
))
363 warning ("target CPU does not support APCS-32" );
364 target_flags
&= ~ ARM_FLAG_APCS_32
;
366 else if (! TARGET_APCS_32
&& !(flags
& FL_MODE26
))
368 warning ("target CPU does not support APCS-26" );
369 target_flags
|= ARM_FLAG_APCS_32
;
372 if (TARGET_THUMB_INTERWORK
&& !(flags
& FL_THUMB
))
374 warning ("target CPU does not support interworking" );
375 target_flags
&= ~ARM_FLAG_THUMB
;
378 /* If interworking is enabled then APCS-32 must be selected as well. */
379 if (TARGET_THUMB_INTERWORK
)
381 if (! TARGET_APCS_32
)
382 warning ("interworking forces APCS-32 to be used" );
383 target_flags
|= ARM_FLAG_APCS_32
;
386 if (TARGET_APCS_STACK
&& ! TARGET_APCS
)
388 warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
389 target_flags
|= ARM_FLAG_APCS_FRAME
;
392 if (write_symbols
!= NO_DEBUG
&& flag_omit_frame_pointer
)
393 warning ("-g with -fomit-frame-pointer may not give sensible debugging");
395 if (TARGET_POKE_FUNCTION_NAME
)
396 target_flags
|= ARM_FLAG_APCS_FRAME
;
398 if (TARGET_APCS_REENT
&& flag_pic
)
399 fatal ("-fpic and -mapcs-reent are incompatible");
401 if (TARGET_APCS_REENT
)
402 warning ("APCS reentrant code not supported. Ignored");
404 /* If stack checking is disabled, we can use r10 as the PIC register,
405 which keeps r9 available. */
406 if (flag_pic
&& ! TARGET_APCS_STACK
)
407 arm_pic_register
= 10;
409 /* Well, I'm about to have a go, but pic is NOT going to be compatible
410 with APCS reentrancy, since that requires too much support in the
411 assembler and linker, and the ARMASM assembler seems to lack some
412 required directives. */
414 warning ("Position independent code not supported");
416 if (TARGET_APCS_FLOAT
)
417 warning ("Passing floating point arguments in fp regs not yet supported");
419 /* Initialise booleans used elsewhere in this file, and in arm.md */
420 arm_fast_multiply
= (flags
& FL_FAST_MULT
) != 0;
421 arm_arch4
= (flags
& FL_ARCH4
) != 0;
422 arm_ld_sched
= (flags
& FL_LDSCHED
) != 0;
423 arm_is_strong
= (flags
& FL_STRONG
);
425 /* The arm.md file needs to know if theprocessor is an ARM6 or an ARM7 */
426 arm_is_6_or_7
= ((flags
& (FL_MODE26
| FL_MODE32
)) && !(flags
& FL_ARCH4
));
428 /* Default value for floating point code... if no co-processor
429 bus, then schedule for emulated floating point. Otherwise,
430 assume the user has an FPA.
431 Note: this does not prevent use of floating point instructions,
432 -msoft-float does that. */
433 if ((flags
& FL_CO_PROC
) == 0)
440 if (streq (target_fp_name
, "2"))
441 arm_fpu_arch
= FP_SOFT2
;
442 else if (streq (target_fp_name
, "3"))
443 arm_fpu_arch
= FP_SOFT3
;
445 fatal ("Invalid floating point emulation option: -mfpe-%s",
449 arm_fpu_arch
= FP_DEFAULT
;
451 if (TARGET_FPE
&& arm_fpu
!= FP_HARD
)
454 /* For arm2/3 there is no need to do any scheduling if there is only
455 a floating point emulator, or we are doing software floating-point. */
456 if ((TARGET_SOFT_FLOAT
|| arm_fpu
!= FP_HARD
) && (flags
& FL_MODE32
) == 0)
457 flag_schedule_insns
= flag_schedule_insns_after_reload
= 0;
459 arm_prog_mode
= TARGET_APCS_32
? PROG_MODE_PROG32
: PROG_MODE_PROG26
;
461 if (structure_size_string
!= NULL
)
463 int size
= strtol (structure_size_string
, NULL
, 0);
465 if (size
== 8 || size
== 32)
466 arm_structure_size_boundary
= size
;
468 warning ("Structure size boundary can only be set to 8 or 32");
471 /* If optimizing for space, don't synthesize constants.
472 For processors with load scheduling, it never costs more than 2 cycles
473 to load a constant, and the load scheduler may well reduce that to 1. */
474 if (optimize_size
|| (flags
& FL_LDSCHED
))
475 arm_constant_limit
= 1;
477 /* If optimizing for size, bump the number of instructions that we
478 are prepared to conditionally execute (even on a StrongARM).
479 Otherwise for the StrongARM, which has early execution of branches,
480 a sequence that is worth skipping is shorter. */
482 max_insns_skipped
= 6;
483 else if (arm_is_strong
)
484 max_insns_skipped
= 3;
487 /* Return 1 if it is possible to return using a single instruction */
490 use_return_insn (iscond
)
495 if (!reload_completed
496 || current_function_pretend_args_size
497 || current_function_anonymous_args
498 || ((get_frame_size () + current_function_outgoing_args_size
!= 0)
499 && !(TARGET_APCS
&& frame_pointer_needed
)))
502 /* Can't be done if interworking with Thumb, and any registers have been
503 stacked. Similarly, on StrongARM, conditional returns are expensive
504 if they aren't taken and registers have been stacked. */
505 if (iscond
&& arm_is_strong
&& frame_pointer_needed
)
507 if ((iscond
&& arm_is_strong
)
508 || TARGET_THUMB_INTERWORK
)
509 for (regno
= 0; regno
< 16; regno
++)
510 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
513 /* Can't be done if any of the FPU regs are pushed, since this also
515 for (regno
= 16; regno
< 24; regno
++)
516 if (regs_ever_live
[regno
] && ! call_used_regs
[regno
])
519 /* If a function is naked, don't use the "return" insn. */
520 if (arm_naked_function_p (current_function_decl
))
526 /* Return TRUE if int I is a valid immediate ARM constant. */
532 unsigned HOST_WIDE_INT mask
= ~(unsigned HOST_WIDE_INT
)0xFF;
534 /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must
535 be all zero, or all one. */
536 if ((i
& ~(unsigned HOST_WIDE_INT
) 0xffffffff) != 0
537 && ((i
& ~(unsigned HOST_WIDE_INT
) 0xffffffff)
538 != ((~(unsigned HOST_WIDE_INT
) 0)
539 & ~(unsigned HOST_WIDE_INT
) 0xffffffff)))
542 /* Fast return for 0 and powers of 2 */
543 if ((i
& (i
- 1)) == 0)
548 if ((i
& mask
& (unsigned HOST_WIDE_INT
) 0xffffffff) == 0)
551 (mask
<< 2) | ((mask
& (unsigned HOST_WIDE_INT
) 0xffffffff)
552 >> (32 - 2)) | ~((unsigned HOST_WIDE_INT
) 0xffffffff);
553 } while (mask
!= ~(unsigned HOST_WIDE_INT
) 0xFF);
558 /* Return true if I is a valid constant for the operation CODE. */
560 const_ok_for_op (i
, code
, mode
)
563 enum machine_mode mode
;
565 if (const_ok_for_arm (i
))
571 return const_ok_for_arm (ARM_SIGN_EXTEND (-i
));
573 case MINUS
: /* Should only occur with (MINUS I reg) => rsb */
579 return const_ok_for_arm (ARM_SIGN_EXTEND (~i
));
586 /* Emit a sequence of insns to handle a large constant.
587 CODE is the code of the operation required, it can be any of SET, PLUS,
588 IOR, AND, XOR, MINUS;
589 MODE is the mode in which the operation is being performed;
590 VAL is the integer to operate on;
591 SOURCE is the other operand (a register, or a null-pointer for SET);
592 SUBTARGETS means it is safe to create scratch registers if that will
593 either produce a simpler sequence, or we will want to cse the values.
594 Return value is the number of insns emitted. */
597 arm_split_constant (code
, mode
, val
, target
, source
, subtargets
)
599 enum machine_mode mode
;
605 if (subtargets
|| code
== SET
606 || (GET_CODE (target
) == REG
&& GET_CODE (source
) == REG
607 && REGNO (target
) != REGNO (source
)))
609 if (arm_gen_constant (code
, mode
, val
, target
, source
, 1, 0)
610 > arm_constant_limit
+ (code
!= SET
))
614 /* Currently SET is the only monadic value for CODE, all
615 the rest are diadic. */
616 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (val
)));
621 rtx temp
= subtargets
? gen_reg_rtx (mode
) : target
;
623 emit_insn (gen_rtx_SET (VOIDmode
, temp
, GEN_INT (val
)));
624 /* For MINUS, the value is subtracted from, since we never
625 have subtraction of a constant. */
627 emit_insn (gen_rtx_SET (VOIDmode
, target
,
628 gen_rtx (code
, mode
, temp
, source
)));
630 emit_insn (gen_rtx_SET (VOIDmode
, target
,
631 gen_rtx (code
, mode
, source
, temp
)));
637 return arm_gen_constant (code
, mode
, val
, target
, source
, subtargets
, 1);
640 /* As above, but extra parameter GENERATE which, if clear, suppresses
643 arm_gen_constant (code
, mode
, val
, target
, source
, subtargets
, generate
)
645 enum machine_mode mode
;
654 int can_negate_initial
= 0;
657 int num_bits_set
= 0;
658 int set_sign_bit_copies
= 0;
659 int clear_sign_bit_copies
= 0;
660 int clear_zero_bit_copies
= 0;
661 int set_zero_bit_copies
= 0;
663 unsigned HOST_WIDE_INT temp1
, temp2
;
664 unsigned HOST_WIDE_INT remainder
= val
& 0xffffffff;
666 /* find out which operations are safe for a given CODE. Also do a quick
667 check for degenerate cases; these can occur when DImode operations
679 can_negate_initial
= 1;
683 if (remainder
== 0xffffffff)
686 emit_insn (gen_rtx_SET (VOIDmode
, target
,
687 GEN_INT (ARM_SIGN_EXTEND (val
))));
692 if (reload_completed
&& rtx_equal_p (target
, source
))
695 emit_insn (gen_rtx_SET (VOIDmode
, target
, source
));
704 emit_insn (gen_rtx_SET (VOIDmode
, target
, const0_rtx
));
707 if (remainder
== 0xffffffff)
709 if (reload_completed
&& rtx_equal_p (target
, source
))
712 emit_insn (gen_rtx_SET (VOIDmode
, target
, source
));
721 if (reload_completed
&& rtx_equal_p (target
, source
))
724 emit_insn (gen_rtx_SET (VOIDmode
, target
, source
));
727 if (remainder
== 0xffffffff)
730 emit_insn (gen_rtx_SET (VOIDmode
, target
,
731 gen_rtx_NOT (mode
, source
)));
735 /* We don't know how to handle this yet below. */
739 /* We treat MINUS as (val - source), since (source - val) is always
740 passed as (source + (-val)). */
744 emit_insn (gen_rtx_SET (VOIDmode
, target
,
745 gen_rtx_NEG (mode
, source
)));
748 if (const_ok_for_arm (val
))
751 emit_insn (gen_rtx_SET (VOIDmode
, target
,
752 gen_rtx_MINUS (mode
, GEN_INT (val
),
764 /* If we can do it in one insn get out quickly */
765 if (const_ok_for_arm (val
)
766 || (can_negate_initial
&& const_ok_for_arm (-val
))
767 || (can_invert
&& const_ok_for_arm (~val
)))
770 emit_insn (gen_rtx_SET (VOIDmode
, target
,
771 (source
? gen_rtx (code
, mode
, source
,
778 /* Calculate a few attributes that may be useful for specific
781 for (i
= 31; i
>= 0; i
--)
783 if ((remainder
& (1 << i
)) == 0)
784 clear_sign_bit_copies
++;
789 for (i
= 31; i
>= 0; i
--)
791 if ((remainder
& (1 << i
)) != 0)
792 set_sign_bit_copies
++;
797 for (i
= 0; i
<= 31; i
++)
799 if ((remainder
& (1 << i
)) == 0)
800 clear_zero_bit_copies
++;
805 for (i
= 0; i
<= 31; i
++)
807 if ((remainder
& (1 << i
)) != 0)
808 set_zero_bit_copies
++;
816 /* See if we can do this by sign_extending a constant that is known
817 to be negative. This is a good, way of doing it, since the shift
818 may well merge into a subsequent insn. */
819 if (set_sign_bit_copies
> 1)
822 (temp1
= ARM_SIGN_EXTEND (remainder
823 << (set_sign_bit_copies
- 1))))
827 rtx new_src
= subtargets
? gen_reg_rtx (mode
) : target
;
828 emit_insn (gen_rtx_SET (VOIDmode
, new_src
,
830 emit_insn (gen_ashrsi3 (target
, new_src
,
831 GEN_INT (set_sign_bit_copies
- 1)));
835 /* For an inverted constant, we will need to set the low bits,
836 these will be shifted out of harm's way. */
837 temp1
|= (1 << (set_sign_bit_copies
- 1)) - 1;
838 if (const_ok_for_arm (~temp1
))
842 rtx new_src
= subtargets
? gen_reg_rtx (mode
) : target
;
843 emit_insn (gen_rtx_SET (VOIDmode
, new_src
,
845 emit_insn (gen_ashrsi3 (target
, new_src
,
846 GEN_INT (set_sign_bit_copies
- 1)));
852 /* See if we can generate this by setting the bottom (or the top)
853 16 bits, and then shifting these into the other half of the
854 word. We only look for the simplest cases, to do more would cost
855 too much. Be careful, however, not to generate this when the
856 alternative would take fewer insns. */
857 if (val
& 0xffff0000)
859 temp1
= remainder
& 0xffff0000;
860 temp2
= remainder
& 0x0000ffff;
862 /* Overlaps outside this range are best done using other methods. */
863 for (i
= 9; i
< 24; i
++)
865 if ((((temp2
| (temp2
<< i
)) & 0xffffffff) == remainder
)
866 && ! const_ok_for_arm (temp2
))
868 rtx new_src
= (subtargets
869 ? (generate
? gen_reg_rtx (mode
) : NULL_RTX
)
871 insns
= arm_gen_constant (code
, mode
, temp2
, new_src
,
872 source
, subtargets
, generate
);
875 emit_insn (gen_rtx_SET
878 gen_rtx_ASHIFT (mode
, source
,
885 /* Don't duplicate cases already considered. */
886 for (i
= 17; i
< 24; i
++)
888 if (((temp1
| (temp1
>> i
)) == remainder
)
889 && ! const_ok_for_arm (temp1
))
891 rtx new_src
= (subtargets
892 ? (generate
? gen_reg_rtx (mode
) : NULL_RTX
)
894 insns
= arm_gen_constant (code
, mode
, temp1
, new_src
,
895 source
, subtargets
, generate
);
899 (gen_rtx_SET (VOIDmode
, target
,
902 gen_rtx_LSHIFTRT (mode
, source
,
913 /* If we have IOR or XOR, and the constant can be loaded in a
914 single instruction, and we can find a temporary to put it in,
915 then this can be done in two instructions instead of 3-4. */
917 /* TARGET can't be NULL if SUBTARGETS is 0 */
918 || (reload_completed
&& ! reg_mentioned_p (target
, source
)))
920 if (const_ok_for_arm (ARM_SIGN_EXTEND (~ val
)))
924 rtx sub
= subtargets
? gen_reg_rtx (mode
) : target
;
926 emit_insn (gen_rtx_SET (VOIDmode
, sub
, GEN_INT (val
)));
927 emit_insn (gen_rtx_SET (VOIDmode
, target
,
928 gen_rtx (code
, mode
, source
, sub
)));
937 if (set_sign_bit_copies
> 8
938 && (val
& (-1 << (32 - set_sign_bit_copies
))) == val
)
942 rtx sub
= subtargets
? gen_reg_rtx (mode
) : target
;
943 rtx shift
= GEN_INT (set_sign_bit_copies
);
945 emit_insn (gen_rtx_SET (VOIDmode
, sub
,
947 gen_rtx_ASHIFT (mode
,
950 emit_insn (gen_rtx_SET (VOIDmode
, target
,
952 gen_rtx_LSHIFTRT (mode
, sub
,
958 if (set_zero_bit_copies
> 8
959 && (remainder
& ((1 << set_zero_bit_copies
) - 1)) == remainder
)
963 rtx sub
= subtargets
? gen_reg_rtx (mode
) : target
;
964 rtx shift
= GEN_INT (set_zero_bit_copies
);
966 emit_insn (gen_rtx_SET (VOIDmode
, sub
,
968 gen_rtx_LSHIFTRT (mode
,
971 emit_insn (gen_rtx_SET (VOIDmode
, target
,
973 gen_rtx_ASHIFT (mode
, sub
,
979 if (const_ok_for_arm (temp1
= ARM_SIGN_EXTEND (~ val
)))
983 rtx sub
= subtargets
? gen_reg_rtx (mode
) : target
;
984 emit_insn (gen_rtx_SET (VOIDmode
, sub
,
985 gen_rtx_NOT (mode
, source
)));
988 sub
= gen_reg_rtx (mode
);
989 emit_insn (gen_rtx_SET (VOIDmode
, sub
,
990 gen_rtx_AND (mode
, source
,
992 emit_insn (gen_rtx_SET (VOIDmode
, target
,
993 gen_rtx_NOT (mode
, sub
)));
1000 /* See if two shifts will do 2 or more insn's worth of work. */
1001 if (clear_sign_bit_copies
>= 16 && clear_sign_bit_copies
< 24)
1003 HOST_WIDE_INT shift_mask
= ((0xffffffff
1004 << (32 - clear_sign_bit_copies
))
1007 if ((remainder
| shift_mask
) != 0xffffffff)
1011 rtx new_src
= subtargets
? gen_reg_rtx (mode
) : target
;
1012 insns
= arm_gen_constant (AND
, mode
, remainder
| shift_mask
,
1013 new_src
, source
, subtargets
, 1);
1018 rtx targ
= subtargets
? NULL_RTX
: target
;
1019 insns
= arm_gen_constant (AND
, mode
, remainder
| shift_mask
,
1020 targ
, source
, subtargets
, 0);
1026 rtx new_src
= subtargets
? gen_reg_rtx (mode
) : target
;
1027 rtx shift
= GEN_INT (clear_sign_bit_copies
);
1029 emit_insn (gen_ashlsi3 (new_src
, source
, shift
));
1030 emit_insn (gen_lshrsi3 (target
, new_src
, shift
));
1036 if (clear_zero_bit_copies
>= 16 && clear_zero_bit_copies
< 24)
1038 HOST_WIDE_INT shift_mask
= (1 << clear_zero_bit_copies
) - 1;
1040 if ((remainder
| shift_mask
) != 0xffffffff)
1044 rtx new_src
= subtargets
? gen_reg_rtx (mode
) : target
;
1046 insns
= arm_gen_constant (AND
, mode
, remainder
| shift_mask
,
1047 new_src
, source
, subtargets
, 1);
1052 rtx targ
= subtargets
? NULL_RTX
: target
;
1054 insns
= arm_gen_constant (AND
, mode
, remainder
| shift_mask
,
1055 targ
, source
, subtargets
, 0);
1061 rtx new_src
= subtargets
? gen_reg_rtx (mode
) : target
;
1062 rtx shift
= GEN_INT (clear_zero_bit_copies
);
1064 emit_insn (gen_lshrsi3 (new_src
, source
, shift
));
1065 emit_insn (gen_ashlsi3 (target
, new_src
, shift
));
1077 for (i
= 0; i
< 32; i
++)
1078 if (remainder
& (1 << i
))
1081 if (code
== AND
|| (can_invert
&& num_bits_set
> 16))
1082 remainder
= (~remainder
) & 0xffffffff;
1083 else if (code
== PLUS
&& num_bits_set
> 16)
1084 remainder
= (-remainder
) & 0xffffffff;
1091 /* Now try and find a way of doing the job in either two or three
1093 We start by looking for the largest block of zeros that are aligned on
1094 a 2-bit boundary, we then fill up the temps, wrapping around to the
1095 top of the word when we drop off the bottom.
1096 In the worst case this code should produce no more than four insns. */
1099 int best_consecutive_zeros
= 0;
1101 for (i
= 0; i
< 32; i
+= 2)
1103 int consecutive_zeros
= 0;
1105 if (! (remainder
& (3 << i
)))
1107 while ((i
< 32) && ! (remainder
& (3 << i
)))
1109 consecutive_zeros
+= 2;
1112 if (consecutive_zeros
> best_consecutive_zeros
)
1114 best_consecutive_zeros
= consecutive_zeros
;
1115 best_start
= i
- consecutive_zeros
;
1121 /* Now start emitting the insns, starting with the one with the highest
1122 bit set: we do this so that the smallest number will be emitted last;
1123 this is more likely to be combinable with addressing insns. */
1131 if (remainder
& (3 << (i
- 2)))
1136 temp1
= remainder
& ((0x0ff << end
)
1137 | ((i
< end
) ? (0xff >> (32 - end
)) : 0));
1138 remainder
&= ~temp1
;
1145 emit_insn (gen_rtx_SET (VOIDmode
,
1146 new_src
= (subtargets
1147 ? gen_reg_rtx (mode
)
1150 ? ~temp1
: temp1
)));
1151 else if (code
== MINUS
)
1152 emit_insn (gen_rtx_SET (VOIDmode
,
1153 new_src
= (subtargets
1154 ? gen_reg_rtx (mode
)
1156 gen_rtx (code
, mode
, GEN_INT (temp1
),
1159 emit_insn (gen_rtx_SET (VOIDmode
,
1160 new_src
= (remainder
1162 ? gen_reg_rtx (mode
)
1165 gen_rtx (code
, mode
, source
,
1166 GEN_INT (can_invert
? ~temp1
1178 else if (code
== MINUS
)
1185 } while (remainder
);
1190 /* Canonicalize a comparison so that we are more likely to recognize it.
1191 This can be done for a few constant compares, where we can make the
1192 immediate value easier to load. */
1194 arm_canonicalize_comparison (code
, op1
)
1198 unsigned HOST_WIDE_INT i
= INTVAL (*op1
);
1208 if (i
!= ((((unsigned HOST_WIDE_INT
) 1) << (HOST_BITS_PER_WIDE_INT
- 1))
1210 && (const_ok_for_arm (i
+1) || const_ok_for_arm (- (i
+1))))
1212 *op1
= GEN_INT (i
+1);
1213 return code
== GT
? GE
: LT
;
1219 if (i
!= (((unsigned HOST_WIDE_INT
) 1) << (HOST_BITS_PER_WIDE_INT
- 1))
1220 && (const_ok_for_arm (i
-1) || const_ok_for_arm (- (i
-1))))
1222 *op1
= GEN_INT (i
-1);
1223 return code
== GE
? GT
: LE
;
1229 if (i
!= ~((unsigned HOST_WIDE_INT
) 0)
1230 && (const_ok_for_arm (i
+1) || const_ok_for_arm (- (i
+1))))
1232 *op1
= GEN_INT (i
+ 1);
1233 return code
== GTU
? GEU
: LTU
;
1240 && (const_ok_for_arm (i
- 1) || const_ok_for_arm (- (i
- 1))))
1242 *op1
= GEN_INT (i
- 1);
1243 return code
== GEU
? GTU
: LEU
;
1254 /* Decide whether a type should be returned in memory (true)
1255 or in a register (false). This is called by the macro
1256 RETURN_IN_MEMORY. */
1258 arm_return_in_memory (type
)
1261 if (! AGGREGATE_TYPE_P (type
))
1263 /* All simple types are returned in registers. */
1266 else if (int_size_in_bytes (type
) > 4)
1268 /* All structures/unions bigger than one word are returned in memory. */
1271 else if (TREE_CODE (type
) == RECORD_TYPE
)
1275 /* For a struct the APCS says that we must return in a register if
1276 every addressable element has an offset of zero. For practical
1277 purposes this means that the structure can have at most one non
1278 bit-field element and that this element must be the first one in
1281 /* Find the first field, ignoring non FIELD_DECL things which will
1282 have been created by C++. */
1283 for (field
= TYPE_FIELDS (type
);
1284 field
&& TREE_CODE (field
) != FIELD_DECL
;
1285 field
= TREE_CHAIN (field
))
1289 return 0; /* An empty structure. Allowed by an extension to ANSI C. */
1291 /* Now check the remaining fields, if any. */
1292 for (field
= TREE_CHAIN (field
);
1294 field
= TREE_CHAIN (field
))
1296 if (TREE_CODE (field
) != FIELD_DECL
)
1299 if (! DECL_BIT_FIELD_TYPE (field
))
1305 else if (TREE_CODE (type
) == UNION_TYPE
)
1309 /* Unions can be returned in registers if every element is
1310 integral, or can be returned in an integer register. */
1311 for (field
= TYPE_FIELDS (type
);
1313 field
= TREE_CHAIN (field
))
1315 if (TREE_CODE (field
) != FIELD_DECL
)
1318 if (FLOAT_TYPE_P (TREE_TYPE (field
)))
1321 if (RETURN_IN_MEMORY (TREE_TYPE (field
)))
1328 /* XXX Not sure what should be done for other aggregates, so put them in
1334 legitimate_pic_operand_p (x
)
1337 if (CONSTANT_P (x
) && flag_pic
1338 && (GET_CODE (x
) == SYMBOL_REF
1339 || (GET_CODE (x
) == CONST
1340 && GET_CODE (XEXP (x
, 0)) == PLUS
1341 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)))
1348 legitimize_pic_address (orig
, mode
, reg
)
1350 enum machine_mode mode
;
1353 if (GET_CODE (orig
) == SYMBOL_REF
)
1355 rtx pic_ref
, address
;
1361 if (reload_in_progress
|| reload_completed
)
1364 reg
= gen_reg_rtx (Pmode
);
1369 #ifdef AOF_ASSEMBLER
1370 /* The AOF assembler can generate relocations for these directly, and
1371 understands that the PIC register has to be added into the offset.
1373 insn
= emit_insn (gen_pic_load_addr_based (reg
, orig
));
1376 address
= gen_reg_rtx (Pmode
);
1380 emit_insn (gen_pic_load_addr (address
, orig
));
1382 pic_ref
= gen_rtx_MEM (Pmode
,
1383 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
1385 RTX_UNCHANGING_P (pic_ref
) = 1;
1386 insn
= emit_move_insn (reg
, pic_ref
);
1388 current_function_uses_pic_offset_table
= 1;
1389 /* Put a REG_EQUAL note on this insn, so that it can be optimized
1391 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_EQUAL
, orig
,
1395 else if (GET_CODE (orig
) == CONST
)
1399 if (GET_CODE (XEXP (orig
, 0)) == PLUS
1400 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
1405 if (reload_in_progress
|| reload_completed
)
1408 reg
= gen_reg_rtx (Pmode
);
1411 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
1413 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
, reg
);
1414 offset
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
1415 base
== reg
? 0 : reg
);
1420 if (GET_CODE (offset
) == CONST_INT
)
1422 /* The base register doesn't really matter, we only want to
1423 test the index for the appropriate mode. */
1424 GO_IF_LEGITIMATE_INDEX (mode
, 0, offset
, win
);
1426 if (! reload_in_progress
&& ! reload_completed
)
1427 offset
= force_reg (Pmode
, offset
);
1432 if (GET_CODE (offset
) == CONST_INT
)
1433 return plus_constant_for_output (base
, INTVAL (offset
));
1436 if (GET_MODE_SIZE (mode
) > 4
1437 && (GET_MODE_CLASS (mode
) == MODE_INT
1438 || TARGET_SOFT_FLOAT
))
1440 emit_insn (gen_addsi3 (reg
, base
, offset
));
1444 return gen_rtx_PLUS (Pmode
, base
, offset
);
1446 else if (GET_CODE (orig
) == LABEL_REF
)
1447 current_function_uses_pic_offset_table
= 1;
1466 #ifndef AOF_ASSEMBLER
1467 rtx l1
, pic_tmp
, pic_tmp2
, seq
;
1468 rtx global_offset_table
;
1470 if (current_function_uses_pic_offset_table
== 0)
1477 l1
= gen_label_rtx ();
1479 global_offset_table
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
1480 /* On the ARM the PC register contains 'dot + 8' at the time of the
1482 pic_tmp
= plus_constant (gen_rtx_LABEL_REF (Pmode
, l1
), 8);
1483 pic_tmp2
= gen_rtx_CONST (VOIDmode
,
1484 gen_rtx_PLUS (Pmode
, global_offset_table
, pc_rtx
));
1486 pic_rtx
= gen_rtx_CONST (Pmode
, gen_rtx_MINUS (Pmode
, pic_tmp2
, pic_tmp
));
1488 emit_insn (gen_pic_load_addr (pic_offset_table_rtx
, pic_rtx
));
1489 emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx
, l1
));
1491 seq
= gen_sequence ();
1493 emit_insn_after (seq
, get_insns ());
1495 /* Need to emit this whether or not we obey regdecls,
1496 since setjmp/longjmp can cause life info to screw up. */
1497 emit_insn (gen_rtx_USE (VOIDmode
, pic_offset_table_rtx
));
1498 #endif /* AOF_ASSEMBLER */
1501 #define REG_OR_SUBREG_REG(X) \
1502 (GET_CODE (X) == REG \
1503 || (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
1505 #define REG_OR_SUBREG_RTX(X) \
1506 (GET_CODE (X) == REG ? (X) : SUBREG_REG (X))
1508 #define ARM_FRAME_RTX(X) \
1509 ((X) == frame_pointer_rtx || (X) == stack_pointer_rtx \
1510 || (X) == arg_pointer_rtx)
1513 arm_rtx_costs (x
, code
, outer_code
)
1515 enum rtx_code code
, outer_code
;
1517 enum machine_mode mode
= GET_MODE (x
);
1518 enum rtx_code subcode
;
1524 /* Memory costs quite a lot for the first word, but subsequent words
1525 load at the equivalent of a single insn each. */
1526 return (10 + 4 * ((GET_MODE_SIZE (mode
) - 1) / UNITS_PER_WORD
)
1527 + (CONSTANT_POOL_ADDRESS_P (x
) ? 4 : 0));
1534 if (mode
== SImode
&& GET_CODE (XEXP (x
, 1)) == REG
)
1541 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
1543 return (8 + (GET_CODE (XEXP (x
, 1)) == CONST_INT
? 0 : 8)
1544 + ((GET_CODE (XEXP (x
, 0)) == REG
1545 || (GET_CODE (XEXP (x
, 0)) == SUBREG
1546 && GET_CODE (SUBREG_REG (XEXP (x
, 0))) == REG
))
1548 return (1 + ((GET_CODE (XEXP (x
, 0)) == REG
1549 || (GET_CODE (XEXP (x
, 0)) == SUBREG
1550 && GET_CODE (SUBREG_REG (XEXP (x
, 0))) == REG
))
1552 + ((GET_CODE (XEXP (x
, 1)) == REG
1553 || (GET_CODE (XEXP (x
, 1)) == SUBREG
1554 && GET_CODE (SUBREG_REG (XEXP (x
, 1))) == REG
)
1555 || (GET_CODE (XEXP (x
, 1)) == CONST_INT
))
1560 return (4 + (REG_OR_SUBREG_REG (XEXP (x
, 1)) ? 0 : 8)
1561 + ((REG_OR_SUBREG_REG (XEXP (x
, 0))
1562 || (GET_CODE (XEXP (x
, 0)) == CONST_INT
1563 && const_ok_for_arm (INTVAL (XEXP (x
, 0)))))
1566 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
1567 return (2 + ((REG_OR_SUBREG_REG (XEXP (x
, 1))
1568 || (GET_CODE (XEXP (x
, 1)) == CONST_DOUBLE
1569 && const_double_rtx_ok_for_fpu (XEXP (x
, 1))))
1571 + ((REG_OR_SUBREG_REG (XEXP (x
, 0))
1572 || (GET_CODE (XEXP (x
, 0)) == CONST_DOUBLE
1573 && const_double_rtx_ok_for_fpu (XEXP (x
, 0))))
1576 if (((GET_CODE (XEXP (x
, 0)) == CONST_INT
1577 && const_ok_for_arm (INTVAL (XEXP (x
, 0)))
1578 && REG_OR_SUBREG_REG (XEXP (x
, 1))))
1579 || (((subcode
= GET_CODE (XEXP (x
, 1))) == ASHIFT
1580 || subcode
== ASHIFTRT
|| subcode
== LSHIFTRT
1581 || subcode
== ROTATE
|| subcode
== ROTATERT
1583 && GET_CODE (XEXP (XEXP (x
, 1), 1)) == CONST_INT
1584 && ((INTVAL (XEXP (XEXP (x
, 1), 1)) &
1585 (INTVAL (XEXP (XEXP (x
, 1), 1)) - 1)) == 0)))
1586 && REG_OR_SUBREG_REG (XEXP (XEXP (x
, 1), 0))
1587 && (REG_OR_SUBREG_REG (XEXP (XEXP (x
, 1), 1))
1588 || GET_CODE (XEXP (XEXP (x
, 1), 1)) == CONST_INT
)
1589 && REG_OR_SUBREG_REG (XEXP (x
, 0))))
1594 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
1595 return (2 + (REG_OR_SUBREG_REG (XEXP (x
, 0)) ? 0 : 8)
1596 + ((REG_OR_SUBREG_REG (XEXP (x
, 1))
1597 || (GET_CODE (XEXP (x
, 1)) == CONST_DOUBLE
1598 && const_double_rtx_ok_for_fpu (XEXP (x
, 1))))
1602 case AND
: case XOR
: case IOR
:
1605 /* Normally the frame registers will be spilt into reg+const during
1606 reload, so it is a bad idea to combine them with other instructions,
1607 since then they might not be moved outside of loops. As a compromise
1608 we allow integration with ops that have a constant as their second
1610 if ((REG_OR_SUBREG_REG (XEXP (x
, 0))
1611 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x
, 0)))
1612 && GET_CODE (XEXP (x
, 1)) != CONST_INT
)
1613 || (REG_OR_SUBREG_REG (XEXP (x
, 0))
1614 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x
, 0)))))
1618 return (4 + extra_cost
+ (REG_OR_SUBREG_REG (XEXP (x
, 0)) ? 0 : 8)
1619 + ((REG_OR_SUBREG_REG (XEXP (x
, 1))
1620 || (GET_CODE (XEXP (x
, 1)) == CONST_INT
1621 && const_ok_for_op (INTVAL (XEXP (x
, 1)), code
, mode
)))
1624 if (REG_OR_SUBREG_REG (XEXP (x
, 0)))
1625 return (1 + (GET_CODE (XEXP (x
, 1)) == CONST_INT
? 0 : extra_cost
)
1626 + ((REG_OR_SUBREG_REG (XEXP (x
, 1))
1627 || (GET_CODE (XEXP (x
, 1)) == CONST_INT
1628 && const_ok_for_op (INTVAL (XEXP (x
, 1)), code
, mode
)))
1631 else if (REG_OR_SUBREG_REG (XEXP (x
, 1)))
1632 return (1 + extra_cost
1633 + ((((subcode
= GET_CODE (XEXP (x
, 0))) == ASHIFT
1634 || subcode
== LSHIFTRT
|| subcode
== ASHIFTRT
1635 || subcode
== ROTATE
|| subcode
== ROTATERT
1637 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
1638 && ((INTVAL (XEXP (XEXP (x
, 0), 1)) &
1639 (INTVAL (XEXP (XEXP (x
, 0), 1)) - 1)) == 0)))
1640 && (REG_OR_SUBREG_REG (XEXP (XEXP (x
, 0), 0)))
1641 && ((REG_OR_SUBREG_REG (XEXP (XEXP (x
, 0), 1)))
1642 || GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
))
1648 /* There is no point basing this on the tuning, since it is always the
1649 fast variant if it exists at all */
1650 if (arm_fast_multiply
&& mode
== DImode
1651 && (GET_CODE (XEXP (x
, 0)) == GET_CODE (XEXP (x
, 1)))
1652 && (GET_CODE (XEXP (x
, 0)) == ZERO_EXTEND
1653 || GET_CODE (XEXP (x
, 0)) == SIGN_EXTEND
))
1656 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
1660 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1662 unsigned HOST_WIDE_INT i
= (INTVAL (XEXP (x
, 1))
1663 & (unsigned HOST_WIDE_INT
) 0xffffffff);
1664 int add_cost
= const_ok_for_arm (i
) ? 4 : 8;
1666 /* Tune as appropriate */
1667 int booth_unit_size
= (arm_fast_multiply
? 8 : 2);
1669 for (j
= 0; i
&& j
< 32; j
+= booth_unit_size
)
1671 i
>>= booth_unit_size
;
1678 return ((arm_fast_multiply
? 8 : 30)
1679 + (REG_OR_SUBREG_REG (XEXP (x
, 0)) ? 0 : 4)
1680 + (REG_OR_SUBREG_REG (XEXP (x
, 1)) ? 0 : 4));
1683 if (arm_fast_multiply
&& mode
== SImode
1684 && GET_CODE (XEXP (x
, 0)) == LSHIFTRT
1685 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == MULT
1686 && (GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0))
1687 == GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 1)))
1688 && (GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == ZERO_EXTEND
1689 || GET_CODE (XEXP (XEXP (XEXP (x
, 0), 0), 0)) == SIGN_EXTEND
))
1694 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
1695 return 4 + (REG_OR_SUBREG_REG (XEXP (x
, 0)) ? 0 : 6);
1699 return 4 + (REG_OR_SUBREG_REG (XEXP (x
, 0)) ? 0 : 4);
1701 return 1 + (REG_OR_SUBREG_REG (XEXP (x
, 0)) ? 0 : 4);
1704 if (GET_CODE (XEXP (x
, 1)) == PC
|| GET_CODE (XEXP (x
, 2)) == PC
)
1712 return 4 + (mode
== DImode
? 4 : 0);
1715 if (GET_MODE (XEXP (x
, 0)) == QImode
)
1716 return (4 + (mode
== DImode
? 4 : 0)
1717 + (GET_CODE (XEXP (x
, 0)) == MEM
? 10 : 0));
1720 switch (GET_MODE (XEXP (x
, 0)))
1723 return (1 + (mode
== DImode
? 4 : 0)
1724 + (GET_CODE (XEXP (x
, 0)) == MEM
? 10 : 0));
1727 return (4 + (mode
== DImode
? 4 : 0)
1728 + (GET_CODE (XEXP (x
, 0)) == MEM
? 10 : 0));
1731 return (1 + (GET_CODE (XEXP (x
, 0)) == MEM
? 10 : 0));
1744 arm_adjust_cost (insn
, link
, dep
, cost
)
1752 /* XXX This is not strictly true for the FPA. */
1753 if (REG_NOTE_KIND(link
) == REG_DEP_ANTI
1754 || REG_NOTE_KIND(link
) == REG_DEP_OUTPUT
)
1757 if ((i_pat
= single_set (insn
)) != NULL
1758 && GET_CODE (SET_SRC (i_pat
)) == MEM
1759 && (d_pat
= single_set (dep
)) != NULL
1760 && GET_CODE (SET_DEST (d_pat
)) == MEM
)
1762 /* This is a load after a store, there is no conflict if the load reads
1763 from a cached area. Assume that loads from the stack, and from the
1764 constant pool are cached, and that others will miss. This is a
1767 /* debug_rtx (insn);
1770 fprintf (stderr, "costs %d\n", cost); */
1772 if (CONSTANT_POOL_ADDRESS_P (XEXP (SET_SRC (i_pat
), 0))
1773 || reg_mentioned_p (stack_pointer_rtx
, XEXP (SET_SRC (i_pat
), 0))
1774 || reg_mentioned_p (frame_pointer_rtx
, XEXP (SET_SRC (i_pat
), 0))
1775 || reg_mentioned_p (hard_frame_pointer_rtx
,
1776 XEXP (SET_SRC (i_pat
), 0)))
1778 /* fprintf (stderr, "***** Now 1\n"); */
1786 /* This code has been fixed for cross compilation. */
1788 static int fpa_consts_inited
= 0;
1790 char *strings_fpa
[8] = {
1792 "4", "5", "0.5", "10"
1795 static REAL_VALUE_TYPE values_fpa
[8];
1803 for (i
= 0; i
< 8; i
++)
1805 r
= REAL_VALUE_ATOF (strings_fpa
[i
], DFmode
);
1809 fpa_consts_inited
= 1;
1812 /* Return TRUE if rtx X is a valid immediate FPU constant. */
1815 const_double_rtx_ok_for_fpu (x
)
1821 if (!fpa_consts_inited
)
1824 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
1825 if (REAL_VALUE_MINUS_ZERO (r
))
1828 for (i
= 0; i
< 8; i
++)
1829 if (REAL_VALUES_EQUAL (r
, values_fpa
[i
]))
1835 /* Return TRUE if rtx X is a valid immediate FPU constant. */
1838 neg_const_double_rtx_ok_for_fpu (x
)
1844 if (!fpa_consts_inited
)
1847 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
1848 r
= REAL_VALUE_NEGATE (r
);
1849 if (REAL_VALUE_MINUS_ZERO (r
))
1852 for (i
= 0; i
< 8; i
++)
1853 if (REAL_VALUES_EQUAL (r
, values_fpa
[i
]))
1859 /* Predicates for `match_operand' and `match_operator'. */
1861 /* s_register_operand is the same as register_operand, but it doesn't accept
1864 This function exists because at the time it was put in it led to better
1865 code. SUBREG(MEM) always needs a reload in the places where
1866 s_register_operand is used, and this seemed to lead to excessive
1870 s_register_operand (op
, mode
)
1872 enum machine_mode mode
;
1874 if (GET_MODE (op
) != mode
&& mode
!= VOIDmode
)
1877 if (GET_CODE (op
) == SUBREG
)
1878 op
= SUBREG_REG (op
);
1880 /* We don't consider registers whose class is NO_REGS
1881 to be a register operand. */
1882 return (GET_CODE (op
) == REG
1883 && (REGNO (op
) >= FIRST_PSEUDO_REGISTER
1884 || REGNO_REG_CLASS (REGNO (op
)) != NO_REGS
));
1887 /* Only accept reg, subreg(reg), const_int. */
1890 reg_or_int_operand (op
, mode
)
1892 enum machine_mode mode
;
1894 if (GET_CODE (op
) == CONST_INT
)
1897 if (GET_MODE (op
) != mode
&& mode
!= VOIDmode
)
1900 if (GET_CODE (op
) == SUBREG
)
1901 op
= SUBREG_REG (op
);
1903 /* We don't consider registers whose class is NO_REGS
1904 to be a register operand. */
1905 return (GET_CODE (op
) == REG
1906 && (REGNO (op
) >= FIRST_PSEUDO_REGISTER
1907 || REGNO_REG_CLASS (REGNO (op
)) != NO_REGS
));
1910 /* Return 1 if OP is an item in memory, given that we are in reload. */
1913 reload_memory_operand (op
, mode
)
1915 enum machine_mode mode
;
1917 int regno
= true_regnum (op
);
1919 return (! CONSTANT_P (op
)
1921 || (GET_CODE (op
) == REG
1922 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)));
1925 /* Return 1 if OP is a valid memory address, but not valid for a signed byte
1926 memory access (architecture V4) */
1928 bad_signed_byte_operand (op
, mode
)
1930 enum machine_mode mode
;
1932 if (! memory_operand (op
, mode
) || GET_CODE (op
) != MEM
)
1937 /* A sum of anything more complex than reg + reg or reg + const is bad */
1938 if ((GET_CODE (op
) == PLUS
|| GET_CODE (op
) == MINUS
)
1939 && (! s_register_operand (XEXP (op
, 0), VOIDmode
)
1940 || (! s_register_operand (XEXP (op
, 1), VOIDmode
)
1941 && GET_CODE (XEXP (op
, 1)) != CONST_INT
)))
1944 /* Big constants are also bad */
1945 if (GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
1946 && (INTVAL (XEXP (op
, 1)) > 0xff
1947 || -INTVAL (XEXP (op
, 1)) > 0xff))
1950 /* Everything else is good, or can will automatically be made so. */
1954 /* Return TRUE for valid operands for the rhs of an ARM instruction. */
1957 arm_rhs_operand (op
, mode
)
1959 enum machine_mode mode
;
1961 return (s_register_operand (op
, mode
)
1962 || (GET_CODE (op
) == CONST_INT
&& const_ok_for_arm (INTVAL (op
))));
1965 /* Return TRUE for valid operands for the rhs of an ARM instruction, or a load.
1969 arm_rhsm_operand (op
, mode
)
1971 enum machine_mode mode
;
1973 return (s_register_operand (op
, mode
)
1974 || (GET_CODE (op
) == CONST_INT
&& const_ok_for_arm (INTVAL (op
)))
1975 || memory_operand (op
, mode
));
1978 /* Return TRUE for valid operands for the rhs of an ARM instruction, or if a
1979 constant that is valid when negated. */
1982 arm_add_operand (op
, mode
)
1984 enum machine_mode mode
;
1986 return (s_register_operand (op
, mode
)
1987 || (GET_CODE (op
) == CONST_INT
1988 && (const_ok_for_arm (INTVAL (op
))
1989 || const_ok_for_arm (-INTVAL (op
)))));
1993 arm_not_operand (op
, mode
)
1995 enum machine_mode mode
;
1997 return (s_register_operand (op
, mode
)
1998 || (GET_CODE (op
) == CONST_INT
1999 && (const_ok_for_arm (INTVAL (op
))
2000 || const_ok_for_arm (~INTVAL (op
)))));
2003 /* Return TRUE if the operand is a memory reference which contains an
2004 offsettable address. */
2006 offsettable_memory_operand (op
, mode
)
2008 enum machine_mode mode
;
2010 if (mode
== VOIDmode
)
2011 mode
= GET_MODE (op
);
2013 return (mode
== GET_MODE (op
)
2014 && GET_CODE (op
) == MEM
2015 && offsettable_address_p (reload_completed
| reload_in_progress
,
2016 mode
, XEXP (op
, 0)));
2019 /* Return TRUE if the operand is a memory reference which is, or can be
2020 made word aligned by adjusting the offset. */
2022 alignable_memory_operand (op
, mode
)
2024 enum machine_mode mode
;
2028 if (mode
== VOIDmode
)
2029 mode
= GET_MODE (op
);
2031 if (mode
!= GET_MODE (op
) || GET_CODE (op
) != MEM
)
2036 return ((GET_CODE (reg
= op
) == REG
2037 || (GET_CODE (op
) == SUBREG
2038 && GET_CODE (reg
= SUBREG_REG (op
)) == REG
)
2039 || (GET_CODE (op
) == PLUS
2040 && GET_CODE (XEXP (op
, 1)) == CONST_INT
2041 && (GET_CODE (reg
= XEXP (op
, 0)) == REG
2042 || (GET_CODE (XEXP (op
, 0)) == SUBREG
2043 && GET_CODE (reg
= SUBREG_REG (XEXP (op
, 0))) == REG
))))
2044 && REGNO_POINTER_ALIGN (REGNO (reg
)) >= 4);
2047 /* Similar to s_register_operand, but does not allow hard integer
2050 f_register_operand (op
, mode
)
2052 enum machine_mode mode
;
2054 if (GET_MODE (op
) != mode
&& mode
!= VOIDmode
)
2057 if (GET_CODE (op
) == SUBREG
)
2058 op
= SUBREG_REG (op
);
2060 /* We don't consider registers whose class is NO_REGS
2061 to be a register operand. */
2062 return (GET_CODE (op
) == REG
2063 && (REGNO (op
) >= FIRST_PSEUDO_REGISTER
2064 || REGNO_REG_CLASS (REGNO (op
)) == FPU_REGS
));
2067 /* Return TRUE for valid operands for the rhs of an FPU instruction. */
2070 fpu_rhs_operand (op
, mode
)
2072 enum machine_mode mode
;
2074 if (s_register_operand (op
, mode
))
2076 else if (GET_CODE (op
) == CONST_DOUBLE
)
2077 return (const_double_rtx_ok_for_fpu (op
));
2083 fpu_add_operand (op
, mode
)
2085 enum machine_mode mode
;
2087 if (s_register_operand (op
, mode
))
2089 else if (GET_CODE (op
) == CONST_DOUBLE
)
2090 return (const_double_rtx_ok_for_fpu (op
)
2091 || neg_const_double_rtx_ok_for_fpu (op
));
2096 /* Return nonzero if OP is a constant power of two. */
2099 power_of_two_operand (op
, mode
)
2101 enum machine_mode mode
;
2103 if (GET_CODE (op
) == CONST_INT
)
2105 HOST_WIDE_INT value
= INTVAL(op
);
2106 return value
!= 0 && (value
& (value
- 1)) == 0;
2111 /* Return TRUE for a valid operand of a DImode operation.
2112 Either: REG, CONST_DOUBLE or MEM(DImode_address).
2113 Note that this disallows MEM(REG+REG), but allows
2114 MEM(PRE/POST_INC/DEC(REG)). */
2117 di_operand (op
, mode
)
2119 enum machine_mode mode
;
2121 if (s_register_operand (op
, mode
))
2124 switch (GET_CODE (op
))
2131 return memory_address_p (DImode
, XEXP (op
, 0));
2138 /* Return TRUE for a valid operand of a DFmode operation when -msoft-float.
2139 Either: REG, CONST_DOUBLE or MEM(DImode_address).
2140 Note that this disallows MEM(REG+REG), but allows
2141 MEM(PRE/POST_INC/DEC(REG)). */
2144 soft_df_operand (op
, mode
)
2146 enum machine_mode mode
;
2148 if (s_register_operand (op
, mode
))
2151 switch (GET_CODE (op
))
2157 return memory_address_p (DFmode
, XEXP (op
, 0));
2164 /* Return TRUE for valid index operands. */
2167 index_operand (op
, mode
)
2169 enum machine_mode mode
;
2171 return (s_register_operand(op
, mode
)
2172 || (immediate_operand (op
, mode
)
2173 && INTVAL (op
) < 4096 && INTVAL (op
) > -4096));
2176 /* Return TRUE for valid shifts by a constant. This also accepts any
2177 power of two on the (somewhat overly relaxed) assumption that the
2178 shift operator in this case was a mult. */
2181 const_shift_operand (op
, mode
)
2183 enum machine_mode mode
;
2185 return (power_of_two_operand (op
, mode
)
2186 || (immediate_operand (op
, mode
)
2187 && (INTVAL (op
) < 32 && INTVAL (op
) > 0)));
2190 /* Return TRUE for arithmetic operators which can be combined with a multiply
2194 shiftable_operator (x
, mode
)
2196 enum machine_mode mode
;
2198 if (GET_MODE (x
) != mode
)
2202 enum rtx_code code
= GET_CODE (x
);
2204 return (code
== PLUS
|| code
== MINUS
2205 || code
== IOR
|| code
== XOR
|| code
== AND
);
2209 /* Return TRUE for shift operators. */
2212 shift_operator (x
, mode
)
2214 enum machine_mode mode
;
2216 if (GET_MODE (x
) != mode
)
2220 enum rtx_code code
= GET_CODE (x
);
2223 return power_of_two_operand (XEXP (x
, 1));
2225 return (code
== ASHIFT
|| code
== ASHIFTRT
|| code
== LSHIFTRT
2226 || code
== ROTATERT
);
2230 int equality_operator (x
, mode
)
2232 enum machine_mode mode
;
2234 return GET_CODE (x
) == EQ
|| GET_CODE (x
) == NE
;
2237 /* Return TRUE for SMIN SMAX UMIN UMAX operators. */
2240 minmax_operator (x
, mode
)
2242 enum machine_mode mode
;
2244 enum rtx_code code
= GET_CODE (x
);
2246 if (GET_MODE (x
) != mode
)
2249 return code
== SMIN
|| code
== SMAX
|| code
== UMIN
|| code
== UMAX
;
2252 /* return TRUE if x is EQ or NE */
2254 /* Return TRUE if this is the condition code register, if we aren't given
2255 a mode, accept any class CCmode register */
2258 cc_register (x
, mode
)
2260 enum machine_mode mode
;
2262 if (mode
== VOIDmode
)
2264 mode
= GET_MODE (x
);
2265 if (GET_MODE_CLASS (mode
) != MODE_CC
)
2269 if (mode
== GET_MODE (x
) && GET_CODE (x
) == REG
&& REGNO (x
) == 24)
2275 /* Return TRUE if this is the condition code register, if we aren't given
2276 a mode, accept any class CCmode register which indicates a dominance
2280 dominant_cc_register (x
, mode
)
2282 enum machine_mode mode
;
2284 if (mode
== VOIDmode
)
2286 mode
= GET_MODE (x
);
2287 if (GET_MODE_CLASS (mode
) != MODE_CC
)
2291 if (mode
!= CC_DNEmode
&& mode
!= CC_DEQmode
2292 && mode
!= CC_DLEmode
&& mode
!= CC_DLTmode
2293 && mode
!= CC_DGEmode
&& mode
!= CC_DGTmode
2294 && mode
!= CC_DLEUmode
&& mode
!= CC_DLTUmode
2295 && mode
!= CC_DGEUmode
&& mode
!= CC_DGTUmode
)
2298 if (mode
== GET_MODE (x
) && GET_CODE (x
) == REG
&& REGNO (x
) == 24)
2304 /* Return TRUE if X references a SYMBOL_REF. */
2306 symbol_mentioned_p (x
)
2312 if (GET_CODE (x
) == SYMBOL_REF
)
2315 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
2316 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
2322 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
2323 if (symbol_mentioned_p (XVECEXP (x
, i
, j
)))
2326 else if (fmt
[i
] == 'e' && symbol_mentioned_p (XEXP (x
, i
)))
2333 /* Return TRUE if X references a LABEL_REF. */
2335 label_mentioned_p (x
)
2341 if (GET_CODE (x
) == LABEL_REF
)
2344 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
2345 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
2351 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
2352 if (label_mentioned_p (XVECEXP (x
, i
, j
)))
2355 else if (fmt
[i
] == 'e' && label_mentioned_p (XEXP (x
, i
)))
2366 enum rtx_code code
= GET_CODE (x
);
2370 else if (code
== SMIN
)
2372 else if (code
== UMIN
)
2374 else if (code
== UMAX
)
2380 /* Return 1 if memory locations are adjacent */
2383 adjacent_mem_locations (a
, b
)
2386 int val0
= 0, val1
= 0;
2389 if ((GET_CODE (XEXP (a
, 0)) == REG
2390 || (GET_CODE (XEXP (a
, 0)) == PLUS
2391 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
2392 && (GET_CODE (XEXP (b
, 0)) == REG
2393 || (GET_CODE (XEXP (b
, 0)) == PLUS
2394 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
2396 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
2398 reg0
= REGNO (XEXP (XEXP (a
, 0), 0));
2399 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
2402 reg0
= REGNO (XEXP (a
, 0));
2403 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
2405 reg1
= REGNO (XEXP (XEXP (b
, 0), 0));
2406 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
2409 reg1
= REGNO (XEXP (b
, 0));
2410 return (reg0
== reg1
) && ((val1
- val0
) == 4 || (val0
- val1
) == 4);
2415 /* Return 1 if OP is a load multiple operation. It is known to be
2416 parallel and the first section will be tested. */
2419 load_multiple_operation (op
, mode
)
2421 enum machine_mode mode
;
2423 HOST_WIDE_INT count
= XVECLEN (op
, 0);
2426 HOST_WIDE_INT i
= 1, base
= 0;
2430 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
)
2433 /* Check to see if this might be a write-back */
2434 if (GET_CODE (SET_SRC (elt
= XVECEXP (op
, 0, 0))) == PLUS
)
2439 /* Now check it more carefully */
2440 if (GET_CODE (SET_DEST (elt
)) != REG
2441 || GET_CODE (XEXP (SET_SRC (elt
), 0)) != REG
2442 || REGNO (XEXP (SET_SRC (elt
), 0)) != REGNO (SET_DEST (elt
))
2443 || GET_CODE (XEXP (SET_SRC (elt
), 1)) != CONST_INT
2444 || INTVAL (XEXP (SET_SRC (elt
), 1)) != (count
- 2) * 4
2445 || GET_CODE (XVECEXP (op
, 0, count
- 1)) != CLOBBER
2446 || GET_CODE (XEXP (XVECEXP (op
, 0, count
- 1), 0)) != REG
2447 || REGNO (XEXP (XVECEXP (op
, 0, count
- 1), 0))
2448 != REGNO (SET_DEST (elt
)))
2454 /* Perform a quick check so we don't blow up below. */
2456 || GET_CODE (XVECEXP (op
, 0, i
- 1)) != SET
2457 || GET_CODE (SET_DEST (XVECEXP (op
, 0, i
- 1))) != REG
2458 || GET_CODE (SET_SRC (XVECEXP (op
, 0, i
- 1))) != MEM
)
2461 dest_regno
= REGNO (SET_DEST (XVECEXP (op
, 0, i
- 1)));
2462 src_addr
= XEXP (SET_SRC (XVECEXP (op
, 0, i
- 1)), 0);
2464 for (; i
< count
; i
++)
2466 elt
= XVECEXP (op
, 0, i
);
2468 if (GET_CODE (elt
) != SET
2469 || GET_CODE (SET_DEST (elt
)) != REG
2470 || GET_MODE (SET_DEST (elt
)) != SImode
2471 || REGNO (SET_DEST (elt
)) != dest_regno
+ i
- base
2472 || GET_CODE (SET_SRC (elt
)) != MEM
2473 || GET_MODE (SET_SRC (elt
)) != SImode
2474 || GET_CODE (XEXP (SET_SRC (elt
), 0)) != PLUS
2475 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt
), 0), 0), src_addr
)
2476 || GET_CODE (XEXP (XEXP (SET_SRC (elt
), 0), 1)) != CONST_INT
2477 || INTVAL (XEXP (XEXP (SET_SRC (elt
), 0), 1)) != (i
- base
) * 4)
2484 /* Return 1 if OP is a store multiple operation. It is known to be
2485 parallel and the first section will be tested. */
2488 store_multiple_operation (op
, mode
)
2490 enum machine_mode mode
;
2492 HOST_WIDE_INT count
= XVECLEN (op
, 0);
2495 HOST_WIDE_INT i
= 1, base
= 0;
2499 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
)
2502 /* Check to see if this might be a write-back */
2503 if (GET_CODE (SET_SRC (elt
= XVECEXP (op
, 0, 0))) == PLUS
)
2508 /* Now check it more carefully */
2509 if (GET_CODE (SET_DEST (elt
)) != REG
2510 || GET_CODE (XEXP (SET_SRC (elt
), 0)) != REG
2511 || REGNO (XEXP (SET_SRC (elt
), 0)) != REGNO (SET_DEST (elt
))
2512 || GET_CODE (XEXP (SET_SRC (elt
), 1)) != CONST_INT
2513 || INTVAL (XEXP (SET_SRC (elt
), 1)) != (count
- 2) * 4
2514 || GET_CODE (XVECEXP (op
, 0, count
- 1)) != CLOBBER
2515 || GET_CODE (XEXP (XVECEXP (op
, 0, count
- 1), 0)) != REG
2516 || REGNO (XEXP (XVECEXP (op
, 0, count
- 1), 0))
2517 != REGNO (SET_DEST (elt
)))
2523 /* Perform a quick check so we don't blow up below. */
2525 || GET_CODE (XVECEXP (op
, 0, i
- 1)) != SET
2526 || GET_CODE (SET_DEST (XVECEXP (op
, 0, i
- 1))) != MEM
2527 || GET_CODE (SET_SRC (XVECEXP (op
, 0, i
- 1))) != REG
)
2530 src_regno
= REGNO (SET_SRC (XVECEXP (op
, 0, i
- 1)));
2531 dest_addr
= XEXP (SET_DEST (XVECEXP (op
, 0, i
- 1)), 0);
2533 for (; i
< count
; i
++)
2535 elt
= XVECEXP (op
, 0, i
);
2537 if (GET_CODE (elt
) != SET
2538 || GET_CODE (SET_SRC (elt
)) != REG
2539 || GET_MODE (SET_SRC (elt
)) != SImode
2540 || REGNO (SET_SRC (elt
)) != src_regno
+ i
- base
2541 || GET_CODE (SET_DEST (elt
)) != MEM
2542 || GET_MODE (SET_DEST (elt
)) != SImode
2543 || GET_CODE (XEXP (SET_DEST (elt
), 0)) != PLUS
2544 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt
), 0), 0), dest_addr
)
2545 || GET_CODE (XEXP (XEXP (SET_DEST (elt
), 0), 1)) != CONST_INT
2546 || INTVAL (XEXP (XEXP (SET_DEST (elt
), 0), 1)) != (i
- base
) * 4)
2554 load_multiple_sequence (operands
, nops
, regs
, base
, load_offset
)
2559 HOST_WIDE_INT
*load_offset
;
2561 int unsorted_regs
[4];
2562 HOST_WIDE_INT unsorted_offsets
[4];
2567 /* Can only handle 2, 3, or 4 insns at present, though could be easily
2568 extended if required. */
2569 if (nops
< 2 || nops
> 4)
2572 /* Loop over the operands and check that the memory references are
2573 suitable (ie immediate offsets from the same base register). At
2574 the same time, extract the target register, and the memory
2576 for (i
= 0; i
< nops
; i
++)
2581 /* Convert a subreg of a mem into the mem itself. */
2582 if (GET_CODE (operands
[nops
+ i
]) == SUBREG
)
2583 operands
[nops
+ i
] = alter_subreg(operands
[nops
+ i
]);
2585 if (GET_CODE (operands
[nops
+ i
]) != MEM
)
2588 /* Don't reorder volatile memory references; it doesn't seem worth
2589 looking for the case where the order is ok anyway. */
2590 if (MEM_VOLATILE_P (operands
[nops
+ i
]))
2593 offset
= const0_rtx
;
2595 if ((GET_CODE (reg
= XEXP (operands
[nops
+ i
], 0)) == REG
2596 || (GET_CODE (reg
) == SUBREG
2597 && GET_CODE (reg
= SUBREG_REG (reg
)) == REG
))
2598 || (GET_CODE (XEXP (operands
[nops
+ i
], 0)) == PLUS
2599 && ((GET_CODE (reg
= XEXP (XEXP (operands
[nops
+ i
], 0), 0))
2601 || (GET_CODE (reg
) == SUBREG
2602 && GET_CODE (reg
= SUBREG_REG (reg
)) == REG
))
2603 && (GET_CODE (offset
= XEXP (XEXP (operands
[nops
+ i
], 0), 1))
2608 base_reg
= REGNO(reg
);
2609 unsorted_regs
[0] = (GET_CODE (operands
[i
]) == REG
2610 ? REGNO (operands
[i
])
2611 : REGNO (SUBREG_REG (operands
[i
])));
2616 if (base_reg
!= REGNO (reg
))
2617 /* Not addressed from the same base register. */
2620 unsorted_regs
[i
] = (GET_CODE (operands
[i
]) == REG
2621 ? REGNO (operands
[i
])
2622 : REGNO (SUBREG_REG (operands
[i
])));
2623 if (unsorted_regs
[i
] < unsorted_regs
[order
[0]])
2627 /* If it isn't an integer register, or if it overwrites the
2628 base register but isn't the last insn in the list, then
2629 we can't do this. */
2630 if (unsorted_regs
[i
] < 0 || unsorted_regs
[i
] > 14
2631 || (i
!= nops
- 1 && unsorted_regs
[i
] == base_reg
))
2634 unsorted_offsets
[i
] = INTVAL (offset
);
2637 /* Not a suitable memory address. */
2641 /* All the useful information has now been extracted from the
2642 operands into unsorted_regs and unsorted_offsets; additionally,
2643 order[0] has been set to the lowest numbered register in the
2644 list. Sort the registers into order, and check that the memory
2645 offsets are ascending and adjacent. */
2647 for (i
= 1; i
< nops
; i
++)
2651 order
[i
] = order
[i
- 1];
2652 for (j
= 0; j
< nops
; j
++)
2653 if (unsorted_regs
[j
] > unsorted_regs
[order
[i
- 1]]
2654 && (order
[i
] == order
[i
- 1]
2655 || unsorted_regs
[j
] < unsorted_regs
[order
[i
]]))
2658 /* Have we found a suitable register? if not, one must be used more
2660 if (order
[i
] == order
[i
- 1])
2663 /* Is the memory address adjacent and ascending? */
2664 if (unsorted_offsets
[order
[i
]] != unsorted_offsets
[order
[i
- 1]] + 4)
2672 for (i
= 0; i
< nops
; i
++)
2673 regs
[i
] = unsorted_regs
[order
[i
]];
2675 *load_offset
= unsorted_offsets
[order
[0]];
2678 if (unsorted_offsets
[order
[0]] == 0)
2679 return 1; /* ldmia */
2681 if (unsorted_offsets
[order
[0]] == 4)
2682 return 2; /* ldmib */
2684 if (unsorted_offsets
[order
[nops
- 1]] == 0)
2685 return 3; /* ldmda */
2687 if (unsorted_offsets
[order
[nops
- 1]] == -4)
2688 return 4; /* ldmdb */
2690 /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if
2691 the offset isn't small enough. The reason 2 ldrs are faster is because
2692 these ARMs are able to do more than one cache access in a single cycle.
2693 The ARM9 and StrongARM have Harvard caches, whilst the ARM8 has a double
2694 bandwidth cache. This means that these cores can do both an instruction
2695 fetch and a data fetch in a single cycle, so the trick of calculating the
2696 address into a scratch register (one of the result regs) and then doing a
2697 load multiple actually becomes slower (and no smaller in code size). That
2698 is the transformation
2700 ldr rd1, [rbase + offset]
2701 ldr rd2, [rbase + offset + 4]
2705 add rd1, rbase, offset
2706 ldmia rd1, {rd1, rd2}
2708 produces worse code -- '3 cycles + any stalls on rd2' instead of '2 cycles
2709 + any stalls on rd2'. On ARMs with only one cache access per cycle, the
2710 first sequence could never complete in less than 6 cycles, whereas the ldm
2711 sequence would only take 5 and would make better use of sequential accesses
2712 if not hitting the cache.
2714 We cheat here and test 'arm_ld_sched' which we currently know to only be
2715 true for the ARM8, ARM9 and StrongARM. If this ever changes, then the test
2716 below needs to be reworked. */
2717 if (nops
== 2 && arm_ld_sched
)
2720 /* Can't do it without setting up the offset, only do this if it takes
2721 no more than one insn. */
2722 return (const_ok_for_arm (unsorted_offsets
[order
[0]])
2723 || const_ok_for_arm (-unsorted_offsets
[order
[0]])) ? 5 : 0;
2727 emit_ldm_seq (operands
, nops
)
2733 HOST_WIDE_INT offset
;
2737 switch (load_multiple_sequence (operands
, nops
, regs
, &base_reg
, &offset
))
2740 strcpy (buf
, "ldm%?ia\t");
2744 strcpy (buf
, "ldm%?ib\t");
2748 strcpy (buf
, "ldm%?da\t");
2752 strcpy (buf
, "ldm%?db\t");
2757 sprintf (buf
, "add%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX
,
2758 reg_names
[regs
[0]], REGISTER_PREFIX
, reg_names
[base_reg
],
2761 sprintf (buf
, "sub%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX
,
2762 reg_names
[regs
[0]], REGISTER_PREFIX
, reg_names
[base_reg
],
2764 output_asm_insn (buf
, operands
);
2766 strcpy (buf
, "ldm%?ia\t");
2773 sprintf (buf
+ strlen (buf
), "%s%s, {%s%s", REGISTER_PREFIX
,
2774 reg_names
[base_reg
], REGISTER_PREFIX
, reg_names
[regs
[0]]);
2776 for (i
= 1; i
< nops
; i
++)
2777 sprintf (buf
+ strlen (buf
), ", %s%s", REGISTER_PREFIX
,
2778 reg_names
[regs
[i
]]);
2780 strcat (buf
, "}\t%@ phole ldm");
2782 output_asm_insn (buf
, operands
);
2787 store_multiple_sequence (operands
, nops
, regs
, base
, load_offset
)
2792 HOST_WIDE_INT
*load_offset
;
2794 int unsorted_regs
[4];
2795 HOST_WIDE_INT unsorted_offsets
[4];
2800 /* Can only handle 2, 3, or 4 insns at present, though could be easily
2801 extended if required. */
2802 if (nops
< 2 || nops
> 4)
2805 /* Loop over the operands and check that the memory references are
2806 suitable (ie immediate offsets from the same base register). At
2807 the same time, extract the target register, and the memory
2809 for (i
= 0; i
< nops
; i
++)
2814 /* Convert a subreg of a mem into the mem itself. */
2815 if (GET_CODE (operands
[nops
+ i
]) == SUBREG
)
2816 operands
[nops
+ i
] = alter_subreg(operands
[nops
+ i
]);
2818 if (GET_CODE (operands
[nops
+ i
]) != MEM
)
2821 /* Don't reorder volatile memory references; it doesn't seem worth
2822 looking for the case where the order is ok anyway. */
2823 if (MEM_VOLATILE_P (operands
[nops
+ i
]))
2826 offset
= const0_rtx
;
2828 if ((GET_CODE (reg
= XEXP (operands
[nops
+ i
], 0)) == REG
2829 || (GET_CODE (reg
) == SUBREG
2830 && GET_CODE (reg
= SUBREG_REG (reg
)) == REG
))
2831 || (GET_CODE (XEXP (operands
[nops
+ i
], 0)) == PLUS
2832 && ((GET_CODE (reg
= XEXP (XEXP (operands
[nops
+ i
], 0), 0))
2834 || (GET_CODE (reg
) == SUBREG
2835 && GET_CODE (reg
= SUBREG_REG (reg
)) == REG
))
2836 && (GET_CODE (offset
= XEXP (XEXP (operands
[nops
+ i
], 0), 1))
2841 base_reg
= REGNO(reg
);
2842 unsorted_regs
[0] = (GET_CODE (operands
[i
]) == REG
2843 ? REGNO (operands
[i
])
2844 : REGNO (SUBREG_REG (operands
[i
])));
2849 if (base_reg
!= REGNO (reg
))
2850 /* Not addressed from the same base register. */
2853 unsorted_regs
[i
] = (GET_CODE (operands
[i
]) == REG
2854 ? REGNO (operands
[i
])
2855 : REGNO (SUBREG_REG (operands
[i
])));
2856 if (unsorted_regs
[i
] < unsorted_regs
[order
[0]])
2860 /* If it isn't an integer register, then we can't do this. */
2861 if (unsorted_regs
[i
] < 0 || unsorted_regs
[i
] > 14)
2864 unsorted_offsets
[i
] = INTVAL (offset
);
2867 /* Not a suitable memory address. */
2871 /* All the useful information has now been extracted from the
2872 operands into unsorted_regs and unsorted_offsets; additionally,
2873 order[0] has been set to the lowest numbered register in the
2874 list. Sort the registers into order, and check that the memory
2875 offsets are ascending and adjacent. */
2877 for (i
= 1; i
< nops
; i
++)
2881 order
[i
] = order
[i
- 1];
2882 for (j
= 0; j
< nops
; j
++)
2883 if (unsorted_regs
[j
] > unsorted_regs
[order
[i
- 1]]
2884 && (order
[i
] == order
[i
- 1]
2885 || unsorted_regs
[j
] < unsorted_regs
[order
[i
]]))
2888 /* Have we found a suitable register? if not, one must be used more
2890 if (order
[i
] == order
[i
- 1])
2893 /* Is the memory address adjacent and ascending? */
2894 if (unsorted_offsets
[order
[i
]] != unsorted_offsets
[order
[i
- 1]] + 4)
2902 for (i
= 0; i
< nops
; i
++)
2903 regs
[i
] = unsorted_regs
[order
[i
]];
2905 *load_offset
= unsorted_offsets
[order
[0]];
2908 if (unsorted_offsets
[order
[0]] == 0)
2909 return 1; /* stmia */
2911 if (unsorted_offsets
[order
[0]] == 4)
2912 return 2; /* stmib */
2914 if (unsorted_offsets
[order
[nops
- 1]] == 0)
2915 return 3; /* stmda */
2917 if (unsorted_offsets
[order
[nops
- 1]] == -4)
2918 return 4; /* stmdb */
2924 emit_stm_seq (operands
, nops
)
2930 HOST_WIDE_INT offset
;
2934 switch (store_multiple_sequence (operands
, nops
, regs
, &base_reg
, &offset
))
2937 strcpy (buf
, "stm%?ia\t");
2941 strcpy (buf
, "stm%?ib\t");
2945 strcpy (buf
, "stm%?da\t");
2949 strcpy (buf
, "stm%?db\t");
2956 sprintf (buf
+ strlen (buf
), "%s%s, {%s%s", REGISTER_PREFIX
,
2957 reg_names
[base_reg
], REGISTER_PREFIX
, reg_names
[regs
[0]]);
2959 for (i
= 1; i
< nops
; i
++)
2960 sprintf (buf
+ strlen (buf
), ", %s%s", REGISTER_PREFIX
,
2961 reg_names
[regs
[i
]]);
2963 strcat (buf
, "}\t%@ phole stm");
2965 output_asm_insn (buf
, operands
);
2970 multi_register_push (op
, mode
)
2972 enum machine_mode mode
;
2974 if (GET_CODE (op
) != PARALLEL
2975 || (GET_CODE (XVECEXP (op
, 0, 0)) != SET
)
2976 || (GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != UNSPEC
)
2977 || (XINT (SET_SRC (XVECEXP (op
, 0, 0)), 1) != 2))
2984 /* Routines for use with attributes */
2986 /* Return nonzero if ATTR is a valid attribute for DECL.
2987 ATTRIBUTES are any existing attributes and ARGS are the arguments
2990 Supported attributes:
2992 naked: don't output any prologue or epilogue code, the user is assumed
2993 to do the right thing. */
2996 arm_valid_machine_decl_attribute (decl
, attributes
, attr
, args
)
3002 if (args
!= NULL_TREE
)
3005 if (is_attribute_p ("naked", attr
))
3006 return TREE_CODE (decl
) == FUNCTION_DECL
;
3010 /* Return non-zero if FUNC is a naked function. */
3013 arm_naked_function_p (func
)
3018 if (TREE_CODE (func
) != FUNCTION_DECL
)
3021 a
= lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func
));
3022 return a
!= NULL_TREE
;
3025 /* Routines for use in generating RTL */
3028 arm_gen_load_multiple (base_regno
, count
, from
, up
, write_back
, unchanging_p
,
3029 in_struct_p
, scalar_p
)
3041 int sign
= up
? 1 : -1;
3044 result
= gen_rtx_PARALLEL (VOIDmode
,
3045 rtvec_alloc (count
+ (write_back
? 2 : 0)));
3048 XVECEXP (result
, 0, 0)
3049 = gen_rtx_SET (GET_MODE (from
), from
,
3050 plus_constant (from
, count
* 4 * sign
));
3055 for (j
= 0; i
< count
; i
++, j
++)
3057 mem
= gen_rtx_MEM (SImode
, plus_constant (from
, j
* 4 * sign
));
3058 RTX_UNCHANGING_P (mem
) = unchanging_p
;
3059 MEM_IN_STRUCT_P (mem
) = in_struct_p
;
3060 MEM_SCALAR_P (mem
) = scalar_p
;
3061 XVECEXP (result
, 0, i
)
3062 = gen_rtx_SET (VOIDmode
, gen_rtx_REG (SImode
, base_regno
+ j
), mem
);
3066 XVECEXP (result
, 0, i
) = gen_rtx_CLOBBER (SImode
, from
);
3072 arm_gen_store_multiple (base_regno
, count
, to
, up
, write_back
, unchanging_p
,
3073 in_struct_p
, scalar_p
)
3085 int sign
= up
? 1 : -1;
3088 result
= gen_rtx_PARALLEL (VOIDmode
,
3089 rtvec_alloc (count
+ (write_back
? 2 : 0)));
3092 XVECEXP (result
, 0, 0)
3093 = gen_rtx_SET (GET_MODE (to
), to
,
3094 plus_constant (to
, count
* 4 * sign
));
3099 for (j
= 0; i
< count
; i
++, j
++)
3101 mem
= gen_rtx_MEM (SImode
, plus_constant (to
, j
* 4 * sign
));
3102 RTX_UNCHANGING_P (mem
) = unchanging_p
;
3103 MEM_IN_STRUCT_P (mem
) = in_struct_p
;
3104 MEM_SCALAR_P (mem
) = scalar_p
;
3106 XVECEXP (result
, 0, i
)
3107 = gen_rtx_SET (VOIDmode
, mem
, gen_rtx_REG (SImode
, base_regno
+ j
));
3111 XVECEXP (result
, 0, i
) = gen_rtx_CLOBBER (SImode
, to
);
3117 arm_gen_movstrqi (operands
)
3120 HOST_WIDE_INT in_words_to_go
, out_words_to_go
, last_bytes
;
3123 rtx st_src
, st_dst
, fin_src
, fin_dst
;
3124 rtx part_bytes_reg
= NULL
;
3126 int dst_unchanging_p
, dst_in_struct_p
, src_unchanging_p
, src_in_struct_p
;
3127 int dst_scalar_p
, src_scalar_p
;
3129 if (GET_CODE (operands
[2]) != CONST_INT
3130 || GET_CODE (operands
[3]) != CONST_INT
3131 || INTVAL (operands
[2]) > 64
3132 || INTVAL (operands
[3]) & 3)
3135 st_dst
= XEXP (operands
[0], 0);
3136 st_src
= XEXP (operands
[1], 0);
3138 dst_unchanging_p
= RTX_UNCHANGING_P (operands
[0]);
3139 dst_in_struct_p
= MEM_IN_STRUCT_P (operands
[0]);
3140 dst_scalar_p
= MEM_SCALAR_P (operands
[0]);
3141 src_unchanging_p
= RTX_UNCHANGING_P (operands
[1]);
3142 src_in_struct_p
= MEM_IN_STRUCT_P (operands
[1]);
3143 src_scalar_p
= MEM_SCALAR_P (operands
[1]);
3145 fin_dst
= dst
= copy_to_mode_reg (SImode
, st_dst
);
3146 fin_src
= src
= copy_to_mode_reg (SImode
, st_src
);
3148 in_words_to_go
= (INTVAL (operands
[2]) + 3) / 4;
3149 out_words_to_go
= INTVAL (operands
[2]) / 4;
3150 last_bytes
= INTVAL (operands
[2]) & 3;
3152 if (out_words_to_go
!= in_words_to_go
&& ((in_words_to_go
- 1) & 3) != 0)
3153 part_bytes_reg
= gen_rtx_REG (SImode
, (in_words_to_go
- 1) & 3);
3155 for (i
= 0; in_words_to_go
>= 2; i
+=4)
3157 if (in_words_to_go
> 4)
3158 emit_insn (arm_gen_load_multiple (0, 4, src
, TRUE
, TRUE
,
3163 emit_insn (arm_gen_load_multiple (0, in_words_to_go
, src
, TRUE
,
3164 FALSE
, src_unchanging_p
,
3165 src_in_struct_p
, src_scalar_p
));
3167 if (out_words_to_go
)
3169 if (out_words_to_go
> 4)
3170 emit_insn (arm_gen_store_multiple (0, 4, dst
, TRUE
, TRUE
,
3174 else if (out_words_to_go
!= 1)
3175 emit_insn (arm_gen_store_multiple (0, out_words_to_go
,
3184 mem
= gen_rtx_MEM (SImode
, dst
);
3185 RTX_UNCHANGING_P (mem
) = dst_unchanging_p
;
3186 MEM_IN_STRUCT_P (mem
) = dst_in_struct_p
;
3187 MEM_SCALAR_P (mem
) = dst_scalar_p
;
3188 emit_move_insn (mem
, gen_rtx_REG (SImode
, 0));
3189 if (last_bytes
!= 0)
3190 emit_insn (gen_addsi3 (dst
, dst
, GEN_INT (4)));
3194 in_words_to_go
-= in_words_to_go
< 4 ? in_words_to_go
: 4;
3195 out_words_to_go
-= out_words_to_go
< 4 ? out_words_to_go
: 4;
3198 /* OUT_WORDS_TO_GO will be zero here if there are byte stores to do. */
3199 if (out_words_to_go
)
3203 mem
= gen_rtx_MEM (SImode
, src
);
3204 RTX_UNCHANGING_P (mem
) = src_unchanging_p
;
3205 MEM_IN_STRUCT_P (mem
) = src_in_struct_p
;
3206 MEM_SCALAR_P (mem
) = src_scalar_p
;
3207 emit_move_insn (sreg
= gen_reg_rtx (SImode
), mem
);
3208 emit_move_insn (fin_src
= gen_reg_rtx (SImode
), plus_constant (src
, 4));
3210 mem
= gen_rtx_MEM (SImode
, dst
);
3211 RTX_UNCHANGING_P (mem
) = dst_unchanging_p
;
3212 MEM_IN_STRUCT_P (mem
) = dst_in_struct_p
;
3213 MEM_SCALAR_P (mem
) = dst_scalar_p
;
3214 emit_move_insn (mem
, sreg
);
3215 emit_move_insn (fin_dst
= gen_reg_rtx (SImode
), plus_constant (dst
, 4));
3218 if (in_words_to_go
) /* Sanity check */
3224 if (in_words_to_go
< 0)
3227 mem
= gen_rtx_MEM (SImode
, src
);
3228 RTX_UNCHANGING_P (mem
) = src_unchanging_p
;
3229 MEM_IN_STRUCT_P (mem
) = src_in_struct_p
;
3230 MEM_SCALAR_P (mem
) = src_scalar_p
;
3231 part_bytes_reg
= copy_to_mode_reg (SImode
, mem
);
3234 if (BYTES_BIG_ENDIAN
&& last_bytes
)
3236 rtx tmp
= gen_reg_rtx (SImode
);
3238 if (part_bytes_reg
== NULL
)
3241 /* The bytes we want are in the top end of the word */
3242 emit_insn (gen_lshrsi3 (tmp
, part_bytes_reg
,
3243 GEN_INT (8 * (4 - last_bytes
))));
3244 part_bytes_reg
= tmp
;
3248 mem
= gen_rtx_MEM (QImode
, plus_constant (dst
, last_bytes
- 1));
3249 RTX_UNCHANGING_P (mem
) = dst_unchanging_p
;
3250 MEM_IN_STRUCT_P (mem
) = dst_in_struct_p
;
3251 MEM_SCALAR_P (mem
) = dst_scalar_p
;
3252 emit_move_insn (mem
, gen_rtx_SUBREG (QImode
, part_bytes_reg
, 0));
3255 tmp
= gen_reg_rtx (SImode
);
3256 emit_insn (gen_lshrsi3 (tmp
, part_bytes_reg
, GEN_INT (8)));
3257 part_bytes_reg
= tmp
;
3266 if (part_bytes_reg
== NULL
)
3269 mem
= gen_rtx_MEM (QImode
, dst
);
3270 RTX_UNCHANGING_P (mem
) = dst_unchanging_p
;
3271 MEM_IN_STRUCT_P (mem
) = dst_in_struct_p
;
3272 MEM_SCALAR_P (mem
) = dst_scalar_p
;
3273 emit_move_insn (mem
, gen_rtx_SUBREG (QImode
, part_bytes_reg
, 0));
3276 rtx tmp
= gen_reg_rtx (SImode
);
3278 emit_insn (gen_addsi3 (dst
, dst
, const1_rtx
));
3279 emit_insn (gen_lshrsi3 (tmp
, part_bytes_reg
, GEN_INT (8)));
3280 part_bytes_reg
= tmp
;
3288 /* Generate a memory reference for a half word, such that it will be loaded
3289 into the top 16 bits of the word. We can assume that the address is
3290 known to be alignable and of the form reg, or plus (reg, const). */
3292 gen_rotated_half_load (memref
)
3295 HOST_WIDE_INT offset
= 0;
3296 rtx base
= XEXP (memref
, 0);
3298 if (GET_CODE (base
) == PLUS
)
3300 offset
= INTVAL (XEXP (base
, 1));
3301 base
= XEXP (base
, 0);
3304 /* If we aren't allowed to generate unaligned addresses, then fail. */
3305 if (TARGET_SHORT_BY_BYTES
3306 && ((BYTES_BIG_ENDIAN
? 1 : 0) ^ ((offset
& 2) == 0)))
3309 base
= gen_rtx_MEM (SImode
, plus_constant (base
, offset
& ~2));
3311 if ((BYTES_BIG_ENDIAN
? 1 : 0) ^ ((offset
& 2) == 2))
3314 return gen_rtx_ROTATE (SImode
, base
, GEN_INT (16));
3317 static enum machine_mode
3318 select_dominance_cc_mode (op
, x
, y
, cond_or
)
3322 HOST_WIDE_INT cond_or
;
3324 enum rtx_code cond1
, cond2
;
3327 /* Currently we will probably get the wrong result if the individual
3328 comparisons are not simple. This also ensures that it is safe to
3329 reverse a comparison if necessary. */
3330 if ((arm_select_cc_mode (cond1
= GET_CODE (x
), XEXP (x
, 0), XEXP (x
, 1))
3332 || (arm_select_cc_mode (cond2
= GET_CODE (y
), XEXP (y
, 0), XEXP (y
, 1))
3337 cond1
= reverse_condition (cond1
);
3339 /* If the comparisons are not equal, and one doesn't dominate the other,
3340 then we can't do this. */
3342 && ! comparison_dominates_p (cond1
, cond2
)
3343 && (swapped
= 1, ! comparison_dominates_p (cond2
, cond1
)))
3348 enum rtx_code temp
= cond1
;
3356 if (cond2
== EQ
|| ! cond_or
)
3361 case LE
: return CC_DLEmode
;
3362 case LEU
: return CC_DLEUmode
;
3363 case GE
: return CC_DGEmode
;
3364 case GEU
: return CC_DGEUmode
;
3371 if (cond2
== LT
|| ! cond_or
)
3380 if (cond2
== GT
|| ! cond_or
)
3389 if (cond2
== LTU
|| ! cond_or
)
3398 if (cond2
== GTU
|| ! cond_or
)
3406 /* The remaining cases only occur when both comparisons are the
3431 arm_select_cc_mode (op
, x
, y
)
3436 /* All floating point compares return CCFP if it is an equality
3437 comparison, and CCFPE otherwise. */
3438 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
3439 return (op
== EQ
|| op
== NE
) ? CCFPmode
: CCFPEmode
;
3441 /* A compare with a shifted operand. Because of canonicalization, the
3442 comparison will have to be swapped when we emit the assembler. */
3443 if (GET_MODE (y
) == SImode
&& GET_CODE (y
) == REG
3444 && (GET_CODE (x
) == ASHIFT
|| GET_CODE (x
) == ASHIFTRT
3445 || GET_CODE (x
) == LSHIFTRT
|| GET_CODE (x
) == ROTATE
3446 || GET_CODE (x
) == ROTATERT
))
3449 /* This is a special case that is used by combine to allow a
3450 comparison of a shifted byte load to be split into a zero-extend
3451 followed by a comparison of the shifted integer (only valid for
3452 equalities and unsigned inequalities). */
3453 if (GET_MODE (x
) == SImode
3454 && GET_CODE (x
) == ASHIFT
3455 && GET_CODE (XEXP (x
, 1)) == CONST_INT
&& INTVAL (XEXP (x
, 1)) == 24
3456 && GET_CODE (XEXP (x
, 0)) == SUBREG
3457 && GET_CODE (SUBREG_REG (XEXP (x
, 0))) == MEM
3458 && GET_MODE (SUBREG_REG (XEXP (x
, 0))) == QImode
3459 && (op
== EQ
|| op
== NE
3460 || op
== GEU
|| op
== GTU
|| op
== LTU
|| op
== LEU
)
3461 && GET_CODE (y
) == CONST_INT
)
3464 /* An operation that sets the condition codes as a side-effect, the
3465 V flag is not set correctly, so we can only use comparisons where
3466 this doesn't matter. (For LT and GE we can use "mi" and "pl"
3468 if (GET_MODE (x
) == SImode
3470 && (op
== EQ
|| op
== NE
|| op
== LT
|| op
== GE
)
3471 && (GET_CODE (x
) == PLUS
|| GET_CODE (x
) == MINUS
3472 || GET_CODE (x
) == AND
|| GET_CODE (x
) == IOR
3473 || GET_CODE (x
) == XOR
|| GET_CODE (x
) == MULT
3474 || GET_CODE (x
) == NOT
|| GET_CODE (x
) == NEG
3475 || GET_CODE (x
) == LSHIFTRT
3476 || GET_CODE (x
) == ASHIFT
|| GET_CODE (x
) == ASHIFTRT
3477 || GET_CODE (x
) == ROTATERT
|| GET_CODE (x
) == ZERO_EXTRACT
))
3480 /* A construct for a conditional compare, if the false arm contains
3481 0, then both conditions must be true, otherwise either condition
3482 must be true. Not all conditions are possible, so CCmode is
3483 returned if it can't be done. */
3484 if (GET_CODE (x
) == IF_THEN_ELSE
3485 && (XEXP (x
, 2) == const0_rtx
3486 || XEXP (x
, 2) == const1_rtx
)
3487 && GET_RTX_CLASS (GET_CODE (XEXP (x
, 0))) == '<'
3488 && GET_RTX_CLASS (GET_CODE (XEXP (x
, 1))) == '<')
3489 return select_dominance_cc_mode (op
, XEXP (x
, 0), XEXP (x
, 1),
3490 INTVAL (XEXP (x
, 2)));
3492 if (GET_MODE (x
) == QImode
&& (op
== EQ
|| op
== NE
))
3495 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
3496 && GET_CODE (x
) == PLUS
3497 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
3503 /* X and Y are two things to compare using CODE. Emit the compare insn and
3504 return the rtx for register 0 in the proper mode. FP means this is a
3505 floating point compare: I don't think that it is needed on the arm. */
3508 gen_compare_reg (code
, x
, y
, fp
)
3513 enum machine_mode mode
= SELECT_CC_MODE (code
, x
, y
);
3514 rtx cc_reg
= gen_rtx_REG (mode
, 24);
3516 emit_insn (gen_rtx_SET (VOIDmode
, cc_reg
,
3517 gen_rtx_COMPARE (mode
, x
, y
)));
3523 arm_reload_in_hi (operands
)
3526 rtx base
= find_replacement (&XEXP (operands
[1], 0));
3528 emit_insn (gen_zero_extendqisi2 (operands
[2], gen_rtx_MEM (QImode
, base
)));
3529 /* Handle the case where the address is too complex to be offset by 1. */
3530 if (GET_CODE (base
) == MINUS
3531 || (GET_CODE (base
) == PLUS
&& GET_CODE (XEXP (base
, 1)) != CONST_INT
))
3533 rtx base_plus
= gen_rtx_REG (SImode
, REGNO (operands
[0]));
3535 emit_insn (gen_rtx_SET (VOIDmode
, base_plus
, base
));
3539 emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode
, operands
[0], 0),
3540 gen_rtx_MEM (QImode
,
3541 plus_constant (base
, 1))));
3542 if (BYTES_BIG_ENDIAN
)
3543 emit_insn (gen_rtx_SET (VOIDmode
, gen_rtx_SUBREG (SImode
, operands
[0], 0),
3544 gen_rtx_IOR (SImode
,
3547 gen_rtx_SUBREG (SImode
, operands
[0], 0),
3551 emit_insn (gen_rtx_SET (VOIDmode
, gen_rtx_SUBREG (SImode
, operands
[0], 0),
3552 gen_rtx_IOR (SImode
,
3553 gen_rtx_ASHIFT (SImode
, operands
[2],
3555 gen_rtx_SUBREG (SImode
, operands
[0],
3560 arm_reload_out_hi (operands
)
3563 rtx base
= find_replacement (&XEXP (operands
[0], 0));
3565 if (BYTES_BIG_ENDIAN
)
3567 emit_insn (gen_movqi (gen_rtx_MEM (QImode
, plus_constant (base
, 1)),
3568 gen_rtx_SUBREG (QImode
, operands
[1], 0)));
3569 emit_insn (gen_lshrsi3 (operands
[2],
3570 gen_rtx_SUBREG (SImode
, operands
[1], 0),
3572 emit_insn (gen_movqi (gen_rtx_MEM (QImode
, base
),
3573 gen_rtx_SUBREG (QImode
, operands
[2], 0)));
3577 emit_insn (gen_movqi (gen_rtx_MEM (QImode
, base
),
3578 gen_rtx_SUBREG (QImode
, operands
[1], 0)));
3579 emit_insn (gen_lshrsi3 (operands
[2],
3580 gen_rtx_SUBREG (SImode
, operands
[1], 0),
3582 emit_insn (gen_movqi (gen_rtx_MEM (QImode
, plus_constant (base
, 1)),
3583 gen_rtx_SUBREG (QImode
, operands
[2], 0)));
3587 /* Routines for manipulation of the constant pool. */
3588 /* This is unashamedly hacked from the version in sh.c, since the problem is
3589 extremely similar. */
3591 /* Arm instructions cannot load a large constant into a register,
3592 constants have to come from a pc relative load. The reference of a pc
3593 relative load instruction must be less than 1k infront of the instruction.
3594 This means that we often have to dump a constant inside a function, and
3595 generate code to branch around it.
3597 It is important to minimize this, since the branches will slow things
3598 down and make things bigger.
3600 Worst case code looks like:
3616 We fix this by performing a scan before scheduling, which notices which
3617 instructions need to have their operands fetched from the constant table
3618 and builds the table.
3623 scan, find an instruction which needs a pcrel move. Look forward, find th
3624 last barrier which is within MAX_COUNT bytes of the requirement.
3625 If there isn't one, make one. Process all the instructions between
3626 the find and the barrier.
3628 In the above example, we can tell that L3 is within 1k of L1, so
3629 the first move can be shrunk from the 2 insn+constant sequence into
3630 just 1 insn, and the constant moved to L3 to make:
3641 Then the second move becomes the target for the shortening process.
3647 rtx value
; /* Value in table */
3648 HOST_WIDE_INT next_offset
;
3649 enum machine_mode mode
; /* Mode of value */
3652 /* The maximum number of constants that can fit into one pool, since
3653 the pc relative range is 0...1020 bytes and constants are at least 4
3656 #define MAX_POOL_SIZE (1020/4)
3657 static pool_node pool_vector
[MAX_POOL_SIZE
];
3658 static int pool_size
;
3659 static rtx pool_vector_label
;
3661 /* Add a constant to the pool and return its offset within the current
3664 X is the rtx we want to replace. MODE is its mode. On return,
3665 ADDRESS_ONLY will be non-zero if we really want the address of such
3666 a constant, not the constant itself. */
3667 static HOST_WIDE_INT
3668 add_constant (x
, mode
, address_only
)
3670 enum machine_mode mode
;
3674 HOST_WIDE_INT offset
;
3678 if (mode
== SImode
&& GET_CODE (x
) == MEM
&& CONSTANT_P (XEXP (x
, 0))
3679 && CONSTANT_POOL_ADDRESS_P (XEXP (x
, 0)))
3680 x
= get_pool_constant (XEXP (x
, 0));
3681 else if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P(x
))
3684 mode
= get_pool_mode (x
);
3685 x
= get_pool_constant (x
);
3687 #ifndef AOF_ASSEMBLER
3688 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == 3)
3689 x
= XVECEXP (x
, 0, 0);
3692 #ifdef AOF_ASSEMBLER
3693 /* PIC Symbol references need to be converted into offsets into the
3695 if (flag_pic
&& GET_CODE (x
) == SYMBOL_REF
)
3696 x
= aof_pic_entry (x
);
3697 #endif /* AOF_ASSEMBLER */
3699 /* First see if we've already got it */
3700 for (i
= 0; i
< pool_size
; i
++)
3702 if (GET_CODE (x
) == pool_vector
[i
].value
->code
3703 && mode
== pool_vector
[i
].mode
)
3705 if (GET_CODE (x
) == CODE_LABEL
)
3707 if (XINT (x
, 3) != XINT (pool_vector
[i
].value
, 3))
3710 if (rtx_equal_p (x
, pool_vector
[i
].value
))
3711 return pool_vector
[i
].next_offset
- GET_MODE_SIZE (mode
);
3715 /* Need a new one */
3716 pool_vector
[pool_size
].next_offset
= GET_MODE_SIZE (mode
);
3719 pool_vector_label
= gen_label_rtx ();
3721 pool_vector
[pool_size
].next_offset
3722 += (offset
= pool_vector
[pool_size
- 1].next_offset
);
3724 pool_vector
[pool_size
].value
= x
;
3725 pool_vector
[pool_size
].mode
= mode
;
3730 /* Output the literal table */
3737 scan
= emit_label_after (gen_label_rtx (), scan
);
3738 scan
= emit_insn_after (gen_align_4 (), scan
);
3739 scan
= emit_label_after (pool_vector_label
, scan
);
3741 for (i
= 0; i
< pool_size
; i
++)
3743 pool_node
*p
= pool_vector
+ i
;
3745 switch (GET_MODE_SIZE (p
->mode
))
3748 scan
= emit_insn_after (gen_consttable_4 (p
->value
), scan
);
3752 scan
= emit_insn_after (gen_consttable_8 (p
->value
), scan
);
3761 scan
= emit_insn_after (gen_consttable_end (), scan
);
3762 scan
= emit_barrier_after (scan
);
3766 /* Non zero if the src operand needs to be fixed up */
3768 fixit (src
, mode
, destreg
)
3770 enum machine_mode mode
;
3773 if (CONSTANT_P (src
))
3775 if (GET_CODE (src
) == CONST_INT
)
3776 return (! const_ok_for_arm (INTVAL (src
))
3777 && ! const_ok_for_arm (~INTVAL (src
)));
3778 if (GET_CODE (src
) == CONST_DOUBLE
)
3779 return (GET_MODE (src
) == VOIDmode
3781 || (! const_double_rtx_ok_for_fpu (src
)
3782 && ! neg_const_double_rtx_ok_for_fpu (src
)));
3783 return symbol_mentioned_p (src
);
3785 #ifndef AOF_ASSEMBLER
3786 else if (GET_CODE (src
) == UNSPEC
&& XINT (src
, 1) == 3)
3790 return (mode
== SImode
&& GET_CODE (src
) == MEM
3791 && GET_CODE (XEXP (src
, 0)) == SYMBOL_REF
3792 && CONSTANT_POOL_ADDRESS_P (XEXP (src
, 0)));
3795 /* Find the last barrier less than MAX_COUNT bytes from FROM, or create one. */
3797 find_barrier (from
, max_count
)
3802 rtx found_barrier
= 0;
3805 while (from
&& count
< max_count
)
3809 if (GET_CODE (from
) == BARRIER
)
3810 found_barrier
= from
;
3812 /* Count the length of this insn */
3813 if (GET_CODE (from
) == INSN
3814 && GET_CODE (PATTERN (from
)) == SET
3815 && CONSTANT_P (SET_SRC (PATTERN (from
)))
3816 && CONSTANT_POOL_ADDRESS_P (SET_SRC (PATTERN (from
))))
3818 /* Handle table jumps as a single entity. */
3819 else if (GET_CODE (from
) == JUMP_INSN
3820 && JUMP_LABEL (from
) != 0
3821 && ((tmp
= next_real_insn (JUMP_LABEL (from
)))
3822 == next_real_insn (from
))
3824 && GET_CODE (tmp
) == JUMP_INSN
3825 && (GET_CODE (PATTERN (tmp
)) == ADDR_VEC
3826 || GET_CODE (PATTERN (tmp
)) == ADDR_DIFF_VEC
))
3828 int elt
= GET_CODE (PATTERN (tmp
)) == ADDR_DIFF_VEC
? 1 : 0;
3829 count
+= (get_attr_length (from
)
3830 + GET_MODE_SIZE (SImode
) * XVECLEN (PATTERN (tmp
), elt
));
3831 /* Continue after the dispatch table. */
3833 from
= NEXT_INSN (tmp
);
3837 count
+= get_attr_length (from
);
3840 from
= NEXT_INSN (from
);
3843 if (! found_barrier
)
3845 /* We didn't find a barrier in time to
3846 dump our stuff, so we'll make one. */
3847 rtx label
= gen_label_rtx ();
3850 from
= PREV_INSN (last
);
3852 from
= get_last_insn ();
3854 /* Walk back to be just before any jump. */
3855 while (GET_CODE (from
) == JUMP_INSN
3856 || GET_CODE (from
) == NOTE
3857 || GET_CODE (from
) == CODE_LABEL
)
3858 from
= PREV_INSN (from
);
3860 from
= emit_jump_insn_after (gen_jump (label
), from
);
3861 JUMP_LABEL (from
) = label
;
3862 found_barrier
= emit_barrier_after (from
);
3863 emit_label_after (label
, found_barrier
);
3866 return found_barrier
;
3869 /* Non zero if the insn is a move instruction which needs to be fixed. */
3874 if (!INSN_DELETED_P (insn
)
3875 && GET_CODE (insn
) == INSN
3876 && GET_CODE (PATTERN (insn
)) == SET
)
3878 rtx pat
= PATTERN (insn
);
3879 rtx src
= SET_SRC (pat
);
3880 rtx dst
= SET_DEST (pat
);
3882 enum machine_mode mode
= GET_MODE (dst
);
3887 if (GET_CODE (dst
) == REG
)
3888 destreg
= REGNO (dst
);
3889 else if (GET_CODE (dst
) == SUBREG
&& GET_CODE (SUBREG_REG (dst
)) == REG
)
3890 destreg
= REGNO (SUBREG_REG (dst
));
3894 return fixit (src
, mode
, destreg
);
3907 /* The ldr instruction can work with up to a 4k offset, and most constants
3908 will be loaded with one of these instructions; however, the adr
3909 instruction and the ldf instructions only work with a 1k offset. This
3910 code needs to be rewritten to use the 4k offset when possible, and to
3911 adjust when a 1k offset is needed. For now we just use a 1k offset
3915 /* Floating point operands can't work further than 1024 bytes from the
3916 PC, so to make things simple we restrict all loads for such functions.
3918 if (TARGET_HARD_FLOAT
)
3922 for (regno
= 16; regno
< 24; regno
++)
3923 if (regs_ever_live
[regno
])
3933 for (insn
= first
; insn
; insn
= NEXT_INSN (insn
))
3935 if (broken_move (insn
))
3937 /* This is a broken move instruction, scan ahead looking for
3938 a barrier to stick the constant table behind */
3940 rtx barrier
= find_barrier (insn
, count_size
);
3942 /* Now find all the moves between the points and modify them */
3943 for (scan
= insn
; scan
!= barrier
; scan
= NEXT_INSN (scan
))
3945 if (broken_move (scan
))
3947 /* This is a broken move instruction, add it to the pool */
3948 rtx pat
= PATTERN (scan
);
3949 rtx src
= SET_SRC (pat
);
3950 rtx dst
= SET_DEST (pat
);
3951 enum machine_mode mode
= GET_MODE (dst
);
3952 HOST_WIDE_INT offset
;
3959 /* If this is an HImode constant load, convert it into
3960 an SImode constant load. Since the register is always
3961 32 bits this is safe. We have to do this, since the
3962 load pc-relative instruction only does a 32-bit load. */
3966 if (GET_CODE (dst
) != REG
)
3968 PUT_MODE (dst
, SImode
);
3971 offset
= add_constant (src
, mode
, &address_only
);
3972 addr
= plus_constant (gen_rtx_LABEL_REF (VOIDmode
,
3976 /* If we only want the address of the pool entry, or
3977 for wide moves to integer regs we need to split
3978 the address calculation off into a separate insn.
3979 If necessary, the load can then be done with a
3980 load-multiple. This is safe, since we have
3981 already noted the length of such insns to be 8,
3982 and we are immediately over-writing the scratch
3983 we have grabbed with the final result. */
3984 if ((address_only
|| GET_MODE_SIZE (mode
) > 4)
3985 && (scratch
= REGNO (dst
)) < 16)
3992 reg
= gen_rtx_REG (SImode
, scratch
);
3994 newinsn
= emit_insn_after (gen_movaddr (reg
, addr
),
4001 newsrc
= gen_rtx_MEM (mode
, addr
);
4003 /* XXX Fixme -- I think the following is bogus. */
4004 /* Build a jump insn wrapper around the move instead
4005 of an ordinary insn, because we want to have room for
4006 the target label rtx in fld[7], which an ordinary
4007 insn doesn't have. */
4009 = emit_jump_insn_after (gen_rtx_SET (VOIDmode
, dst
,
4012 JUMP_LABEL (newinsn
) = pool_vector_label
;
4014 /* But it's still an ordinary insn */
4015 PUT_CODE (newinsn
, INSN
);
4023 dump_table (barrier
);
4030 /* Routines to output assembly language. */
4032 /* If the rtx is the correct value then return the string of the number.
4033 In this way we can ensure that valid double constants are generated even
4034 when cross compiling. */
4036 fp_immediate_constant (x
)
4042 if (!fpa_consts_inited
)
4045 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
4046 for (i
= 0; i
< 8; i
++)
4047 if (REAL_VALUES_EQUAL (r
, values_fpa
[i
]))
4048 return strings_fpa
[i
];
4053 /* As for fp_immediate_constant, but value is passed directly, not in rtx. */
4055 fp_const_from_val (r
)
4060 if (! fpa_consts_inited
)
4063 for (i
= 0; i
< 8; i
++)
4064 if (REAL_VALUES_EQUAL (*r
, values_fpa
[i
]))
4065 return strings_fpa
[i
];
4070 /* Output the operands of a LDM/STM instruction to STREAM.
4071 MASK is the ARM register set mask of which only bits 0-15 are important.
4072 INSTR is the possibly suffixed base register. HAT unequals zero if a hat
4073 must follow the register list. */
4076 print_multi_reg (stream
, instr
, mask
, hat
)
4082 int not_first
= FALSE
;
4084 fputc ('\t', stream
);
4085 fprintf (stream
, instr
, REGISTER_PREFIX
);
4086 fputs (", {", stream
);
4087 for (i
= 0; i
< 16; i
++)
4088 if (mask
& (1 << i
))
4091 fprintf (stream
, ", ");
4092 fprintf (stream
, "%s%s", REGISTER_PREFIX
, reg_names
[i
]);
4096 fprintf (stream
, "}%s\n", hat
? "^" : "");
4099 /* Output a 'call' insn. */
4102 output_call (operands
)
4105 /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
4107 if (REGNO (operands
[0]) == 14)
4109 operands
[0] = gen_rtx_REG (SImode
, 12);
4110 output_asm_insn ("mov%?\t%0, %|lr", operands
);
4112 output_asm_insn ("mov%?\t%|lr, %|pc", operands
);
4114 if (TARGET_THUMB_INTERWORK
)
4115 output_asm_insn ("bx%?\t%0", operands
);
4117 output_asm_insn ("mov%?\t%|pc, %0", operands
);
4126 int something_changed
= 0;
4128 int code
= GET_CODE (x0
);
4135 if (REGNO (x0
) == 14)
4137 *x
= gen_rtx_REG (SImode
, 12);
4142 /* Scan through the sub-elements and change any references there */
4143 fmt
= GET_RTX_FORMAT (code
);
4144 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4146 something_changed
|= eliminate_lr2ip (&XEXP (x0
, i
));
4147 else if (fmt
[i
] == 'E')
4148 for (j
= 0; j
< XVECLEN (x0
, i
); j
++)
4149 something_changed
|= eliminate_lr2ip (&XVECEXP (x0
, i
, j
));
4150 return something_changed
;
4154 /* Output a 'call' insn that is a reference in memory. */
4157 output_call_mem (operands
)
4160 operands
[0] = copy_rtx (operands
[0]); /* Be ultra careful */
4161 /* Handle calls using lr by using ip (which may be clobbered in subr anyway).
4163 if (eliminate_lr2ip (&operands
[0]))
4164 output_asm_insn ("mov%?\t%|ip, %|lr", operands
);
4166 if (TARGET_THUMB_INTERWORK
)
4168 output_asm_insn ("ldr%?\t%|ip, %0", operands
);
4169 output_asm_insn ("mov%?\t%|lr, %|pc", operands
);
4170 output_asm_insn ("bx%?\t%|ip", operands
);
4174 output_asm_insn ("mov%?\t%|lr, %|pc", operands
);
4175 output_asm_insn ("ldr%?\t%|pc, %0", operands
);
4182 /* Output a move from arm registers to an fpu registers.
4183 OPERANDS[0] is an fpu register.
4184 OPERANDS[1] is the first registers of an arm register pair. */
4187 output_mov_long_double_fpu_from_arm (operands
)
4190 int arm_reg0
= REGNO (operands
[1]);
4196 ops
[0] = gen_rtx_REG (SImode
, arm_reg0
);
4197 ops
[1] = gen_rtx_REG (SImode
, 1 + arm_reg0
);
4198 ops
[2] = gen_rtx_REG (SImode
, 2 + arm_reg0
);
4200 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1, %2}", ops
);
4201 output_asm_insn ("ldf%?e\t%0, [%|sp], #12", operands
);
4205 /* Output a move from an fpu register to arm registers.
4206 OPERANDS[0] is the first registers of an arm register pair.
4207 OPERANDS[1] is an fpu register. */
4210 output_mov_long_double_arm_from_fpu (operands
)
4213 int arm_reg0
= REGNO (operands
[0]);
4219 ops
[0] = gen_rtx_REG (SImode
, arm_reg0
);
4220 ops
[1] = gen_rtx_REG (SImode
, 1 + arm_reg0
);
4221 ops
[2] = gen_rtx_REG (SImode
, 2 + arm_reg0
);
4223 output_asm_insn ("stf%?e\t%1, [%|sp, #-12]!", operands
);
4224 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1, %2}", ops
);
4228 /* Output a move from arm registers to arm registers of a long double
4229 OPERANDS[0] is the destination.
4230 OPERANDS[1] is the source. */
4232 output_mov_long_double_arm_from_arm (operands
)
4235 /* We have to be careful here because the two might overlap */
4236 int dest_start
= REGNO (operands
[0]);
4237 int src_start
= REGNO (operands
[1]);
4241 if (dest_start
< src_start
)
4243 for (i
= 0; i
< 3; i
++)
4245 ops
[0] = gen_rtx_REG (SImode
, dest_start
+ i
);
4246 ops
[1] = gen_rtx_REG (SImode
, src_start
+ i
);
4247 output_asm_insn ("mov%?\t%0, %1", ops
);
4252 for (i
= 2; i
>= 0; i
--)
4254 ops
[0] = gen_rtx_REG (SImode
, dest_start
+ i
);
4255 ops
[1] = gen_rtx_REG (SImode
, src_start
+ i
);
4256 output_asm_insn ("mov%?\t%0, %1", ops
);
4264 /* Output a move from arm registers to an fpu registers.
4265 OPERANDS[0] is an fpu register.
4266 OPERANDS[1] is the first registers of an arm register pair. */
4269 output_mov_double_fpu_from_arm (operands
)
4272 int arm_reg0
= REGNO (operands
[1]);
4277 ops
[0] = gen_rtx_REG (SImode
, arm_reg0
);
4278 ops
[1] = gen_rtx_REG (SImode
, 1 + arm_reg0
);
4279 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1}", ops
);
4280 output_asm_insn ("ldf%?d\t%0, [%|sp], #8", operands
);
4284 /* Output a move from an fpu register to arm registers.
4285 OPERANDS[0] is the first registers of an arm register pair.
4286 OPERANDS[1] is an fpu register. */
4289 output_mov_double_arm_from_fpu (operands
)
4292 int arm_reg0
= REGNO (operands
[0]);
4298 ops
[0] = gen_rtx_REG (SImode
, arm_reg0
);
4299 ops
[1] = gen_rtx_REG (SImode
, 1 + arm_reg0
);
4300 output_asm_insn ("stf%?d\t%1, [%|sp, #-8]!", operands
);
4301 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1}", ops
);
4305 /* Output a move between double words.
4306 It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
4307 or MEM<-REG and all MEMs must be offsettable addresses. */
4310 output_move_double (operands
)
4313 enum rtx_code code0
= GET_CODE (operands
[0]);
4314 enum rtx_code code1
= GET_CODE (operands
[1]);
4319 int reg0
= REGNO (operands
[0]);
4321 otherops
[0] = gen_rtx_REG (SImode
, 1 + reg0
);
4324 int reg1
= REGNO (operands
[1]);
4328 /* Ensure the second source is not overwritten */
4329 if (reg1
== reg0
+ (WORDS_BIG_ENDIAN
? -1 : 1))
4330 output_asm_insn("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands
);
4332 output_asm_insn("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands
);
4334 else if (code1
== CONST_DOUBLE
)
4336 if (GET_MODE (operands
[1]) == DFmode
)
4339 union real_extract u
;
4341 bcopy ((char *) &CONST_DOUBLE_LOW (operands
[1]), (char *) &u
,
4343 REAL_VALUE_TO_TARGET_DOUBLE (u
.d
, l
);
4344 otherops
[1] = GEN_INT(l
[1]);
4345 operands
[1] = GEN_INT(l
[0]);
4347 else if (GET_MODE (operands
[1]) != VOIDmode
)
4349 else if (WORDS_BIG_ENDIAN
)
4352 otherops
[1] = GEN_INT (CONST_DOUBLE_LOW (operands
[1]));
4353 operands
[1] = GEN_INT (CONST_DOUBLE_HIGH (operands
[1]));
4358 otherops
[1] = GEN_INT (CONST_DOUBLE_HIGH (operands
[1]));
4359 operands
[1] = GEN_INT (CONST_DOUBLE_LOW (operands
[1]));
4361 output_mov_immediate (operands
);
4362 output_mov_immediate (otherops
);
4364 else if (code1
== CONST_INT
)
4366 #if HOST_BITS_PER_WIDE_INT > 32
4367 /* If HOST_WIDE_INT is more than 32 bits, the intval tells us
4368 what the upper word is. */
4369 if (WORDS_BIG_ENDIAN
)
4371 otherops
[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands
[1])));
4372 operands
[1] = GEN_INT (INTVAL (operands
[1]) >> 32);
4376 otherops
[1] = GEN_INT (INTVAL (operands
[1]) >> 32);
4377 operands
[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands
[1])));
4380 /* Sign extend the intval into the high-order word */
4381 if (WORDS_BIG_ENDIAN
)
4383 otherops
[1] = operands
[1];
4384 operands
[1] = (INTVAL (operands
[1]) < 0
4385 ? constm1_rtx
: const0_rtx
);
4388 otherops
[1] = INTVAL (operands
[1]) < 0 ? constm1_rtx
: const0_rtx
;
4390 output_mov_immediate (otherops
);
4391 output_mov_immediate (operands
);
4393 else if (code1
== MEM
)
4395 switch (GET_CODE (XEXP (operands
[1], 0)))
4398 output_asm_insn ("ldm%?ia\t%m1, %M0", operands
);
4402 abort (); /* Should never happen now */
4406 output_asm_insn ("ldm%?db\t%m1!, %M0", operands
);
4410 output_asm_insn ("ldm%?ia\t%m1!, %M0", operands
);
4414 abort (); /* Should never happen now */
4419 output_asm_insn ("adr%?\t%0, %1", operands
);
4420 output_asm_insn ("ldm%?ia\t%0, %M0", operands
);
4424 if (arm_add_operand (XEXP (XEXP (operands
[1], 0), 1)))
4426 otherops
[0] = operands
[0];
4427 otherops
[1] = XEXP (XEXP (operands
[1], 0), 0);
4428 otherops
[2] = XEXP (XEXP (operands
[1], 0), 1);
4429 if (GET_CODE (XEXP (operands
[1], 0)) == PLUS
)
4431 if (GET_CODE (otherops
[2]) == CONST_INT
)
4433 switch (INTVAL (otherops
[2]))
4436 output_asm_insn ("ldm%?db\t%1, %M0", otherops
);
4439 output_asm_insn ("ldm%?da\t%1, %M0", otherops
);
4442 output_asm_insn ("ldm%?ib\t%1, %M0", otherops
);
4445 if (!(const_ok_for_arm (INTVAL (otherops
[2]))))
4446 output_asm_insn ("sub%?\t%0, %1, #%n2", otherops
);
4448 output_asm_insn ("add%?\t%0, %1, %2", otherops
);
4451 output_asm_insn ("add%?\t%0, %1, %2", otherops
);
4454 output_asm_insn ("sub%?\t%0, %1, %2", otherops
);
4455 return "ldm%?ia\t%0, %M0";
4459 otherops
[1] = adj_offsettable_operand (operands
[1], 4);
4460 /* Take care of overlapping base/data reg. */
4461 if (reg_mentioned_p (operands
[0], operands
[1]))
4463 output_asm_insn ("ldr%?\t%0, %1", otherops
);
4464 output_asm_insn ("ldr%?\t%0, %1", operands
);
4468 output_asm_insn ("ldr%?\t%0, %1", operands
);
4469 output_asm_insn ("ldr%?\t%0, %1", otherops
);
4475 abort(); /* Constraints should prevent this */
4477 else if (code0
== MEM
&& code1
== REG
)
4479 if (REGNO (operands
[1]) == 12)
4482 switch (GET_CODE (XEXP (operands
[0], 0)))
4485 output_asm_insn ("stm%?ia\t%m0, %M1", operands
);
4489 abort (); /* Should never happen now */
4493 output_asm_insn ("stm%?db\t%m0!, %M1", operands
);
4497 output_asm_insn ("stm%?ia\t%m0!, %M1", operands
);
4501 abort (); /* Should never happen now */
4505 if (GET_CODE (XEXP (XEXP (operands
[0], 0), 1)) == CONST_INT
)
4507 switch (INTVAL (XEXP (XEXP (operands
[0], 0), 1)))
4510 output_asm_insn ("stm%?db\t%m0, %M1", operands
);
4514 output_asm_insn ("stm%?da\t%m0, %M1", operands
);
4518 output_asm_insn ("stm%?ib\t%m0, %M1", operands
);
4525 otherops
[0] = adj_offsettable_operand (operands
[0], 4);
4526 otherops
[1] = gen_rtx_REG (SImode
, 1 + REGNO (operands
[1]));
4527 output_asm_insn ("str%?\t%1, %0", operands
);
4528 output_asm_insn ("str%?\t%1, %0", otherops
);
4532 abort(); /* Constraints should prevent this */
4538 /* Output an arbitrary MOV reg, #n.
4539 OPERANDS[0] is a register. OPERANDS[1] is a const_int. */
4542 output_mov_immediate (operands
)
4545 HOST_WIDE_INT n
= INTVAL (operands
[1]);
4549 /* Try to use one MOV */
4550 if (const_ok_for_arm (n
))
4552 output_asm_insn ("mov%?\t%0, %1", operands
);
4556 /* Try to use one MVN */
4557 if (const_ok_for_arm (~n
))
4559 operands
[1] = GEN_INT (~n
);
4560 output_asm_insn ("mvn%?\t%0, %1", operands
);
4564 /* If all else fails, make it out of ORRs or BICs as appropriate. */
4566 for (i
=0; i
< 32; i
++)
4570 if (n_ones
> 16) /* Shorter to use MVN with BIC in this case. */
4571 output_multi_immediate(operands
, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1,
4574 output_multi_immediate(operands
, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1,
4581 /* Output an ADD r, s, #n where n may be too big for one instruction. If
4582 adding zero to one register, output nothing. */
4585 output_add_immediate (operands
)
4588 HOST_WIDE_INT n
= INTVAL (operands
[2]);
4590 if (n
!= 0 || REGNO (operands
[0]) != REGNO (operands
[1]))
4593 output_multi_immediate (operands
,
4594 "sub%?\t%0, %1, %2", "sub%?\t%0, %0, %2", 2,
4597 output_multi_immediate (operands
,
4598 "add%?\t%0, %1, %2", "add%?\t%0, %0, %2", 2,
4605 /* Output a multiple immediate operation.
4606 OPERANDS is the vector of operands referred to in the output patterns.
4607 INSTR1 is the output pattern to use for the first constant.
4608 INSTR2 is the output pattern to use for subsequent constants.
4609 IMMED_OP is the index of the constant slot in OPERANDS.
4610 N is the constant value. */
4613 output_multi_immediate (operands
, instr1
, instr2
, immed_op
, n
)
4615 char *instr1
, *instr2
;
4619 #if HOST_BITS_PER_WIDE_INT > 32
4625 operands
[immed_op
] = const0_rtx
;
4626 output_asm_insn (instr1
, operands
); /* Quick and easy output */
4631 char *instr
= instr1
;
4633 /* Note that n is never zero here (which would give no output) */
4634 for (i
= 0; i
< 32; i
+= 2)
4638 operands
[immed_op
] = GEN_INT (n
& (255 << i
));
4639 output_asm_insn (instr
, operands
);
4649 /* Return the appropriate ARM instruction for the operation code.
4650 The returned result should not be overwritten. OP is the rtx of the
4651 operation. SHIFT_FIRST_ARG is TRUE if the first argument of the operator
4655 arithmetic_instr (op
, shift_first_arg
)
4657 int shift_first_arg
;
4659 switch (GET_CODE (op
))
4665 return shift_first_arg
? "rsb" : "sub";
4682 /* Ensure valid constant shifts and return the appropriate shift mnemonic
4683 for the operation code. The returned result should not be overwritten.
4684 OP is the rtx code of the shift.
4685 On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
4689 shift_op (op
, amountp
)
4691 HOST_WIDE_INT
*amountp
;
4694 enum rtx_code code
= GET_CODE (op
);
4696 if (GET_CODE (XEXP (op
, 1)) == REG
|| GET_CODE (XEXP (op
, 1)) == SUBREG
)
4698 else if (GET_CODE (XEXP (op
, 1)) == CONST_INT
)
4699 *amountp
= INTVAL (XEXP (op
, 1));
4722 /* We never have to worry about the amount being other than a
4723 power of 2, since this case can never be reloaded from a reg. */
4725 *amountp
= int_log2 (*amountp
);
4736 /* This is not 100% correct, but follows from the desire to merge
4737 multiplication by a power of 2 with the recognizer for a
4738 shift. >=32 is not a valid shift for "asl", so we must try and
4739 output a shift that produces the correct arithmetical result.
4740 Using lsr #32 is identical except for the fact that the carry bit
4741 is not set correctly if we set the flags; but we never use the
4742 carry bit from such an operation, so we can ignore that. */
4743 if (code
== ROTATERT
)
4744 *amountp
&= 31; /* Rotate is just modulo 32 */
4745 else if (*amountp
!= (*amountp
& 31))
4752 /* Shifts of 0 are no-ops. */
4761 /* Obtain the shift from the POWER of two. */
4763 static HOST_WIDE_INT
4765 HOST_WIDE_INT power
;
4767 HOST_WIDE_INT shift
= 0;
4769 while (((((HOST_WIDE_INT
) 1) << shift
) & power
) == 0)
4779 /* Output a .ascii pseudo-op, keeping track of lengths. This is because
4780 /bin/as is horribly restrictive. */
4783 output_ascii_pseudo_op (stream
, p
, len
)
4789 int len_so_far
= 1000;
4790 int chars_so_far
= 0;
4792 for (i
= 0; i
< len
; i
++)
4794 register int c
= p
[i
];
4796 if (len_so_far
> 50)
4799 fputs ("\"\n", stream
);
4800 fputs ("\t.ascii\t\"", stream
);
4805 if (c
== '\"' || c
== '\\')
4811 if (c
>= ' ' && c
< 0177)
4818 fprintf (stream
, "\\%03o", c
);
4825 fputs ("\"\n", stream
);
4829 /* Try to determine whether a pattern really clobbers the link register.
4830 This information is useful when peepholing, so that lr need not be pushed
4831 if we combine a call followed by a return.
4832 NOTE: This code does not check for side-effect expressions in a SET_SRC:
4833 such a check should not be needed because these only update an existing
4834 value within a register; the register must still be set elsewhere within
4838 pattern_really_clobbers_lr (x
)
4843 switch (GET_CODE (x
))
4846 switch (GET_CODE (SET_DEST (x
)))
4849 return REGNO (SET_DEST (x
)) == 14;
4852 if (GET_CODE (XEXP (SET_DEST (x
), 0)) == REG
)
4853 return REGNO (XEXP (SET_DEST (x
), 0)) == 14;
4855 if (GET_CODE (XEXP (SET_DEST (x
), 0)) == MEM
)
4864 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
4865 if (pattern_really_clobbers_lr (XVECEXP (x
, 0, i
)))
4870 switch (GET_CODE (XEXP (x
, 0)))
4873 return REGNO (XEXP (x
, 0)) == 14;
4876 if (GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
)
4877 return REGNO (XEXP (XEXP (x
, 0), 0)) == 14;
4893 function_really_clobbers_lr (first
)
4898 for (insn
= first
; insn
; insn
= next_nonnote_insn (insn
))
4900 switch (GET_CODE (insn
))
4905 case JUMP_INSN
: /* Jump insns only change the PC (and conds) */
4910 if (pattern_really_clobbers_lr (PATTERN (insn
)))
4915 /* Don't yet know how to handle those calls that are not to a
4917 if (GET_CODE (PATTERN (insn
)) != PARALLEL
)
4920 switch (GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)))
4923 if (GET_CODE (XEXP (XEXP (XVECEXP (PATTERN (insn
), 0, 0), 0), 0))
4929 if (GET_CODE (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn
),
4935 default: /* Don't recognize it, be safe */
4939 /* A call can be made (by peepholing) not to clobber lr iff it is
4940 followed by a return. There may, however, be a use insn iff
4941 we are returning the result of the call.
4942 If we run off the end of the insn chain, then that means the
4943 call was at the end of the function. Unfortunately we don't
4944 have a return insn for the peephole to recognize, so we
4945 must reject this. (Can this be fixed by adding our own insn?) */
4946 if ((next
= next_nonnote_insn (insn
)) == NULL
)
4949 /* No need to worry about lr if the call never returns */
4950 if (GET_CODE (next
) == BARRIER
)
4953 if (GET_CODE (next
) == INSN
&& GET_CODE (PATTERN (next
)) == USE
4954 && (GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == SET
)
4955 && (REGNO (SET_DEST (XVECEXP (PATTERN (insn
), 0, 0)))
4956 == REGNO (XEXP (PATTERN (next
), 0))))
4957 if ((next
= next_nonnote_insn (next
)) == NULL
)
4960 if (GET_CODE (next
) == JUMP_INSN
4961 && GET_CODE (PATTERN (next
)) == RETURN
)
4970 /* We have reached the end of the chain so lr was _not_ clobbered */
4975 output_return_instruction (operand
, really_return
, reverse
)
4981 int reg
, live_regs
= 0;
4982 int volatile_func
= (optimize
> 0
4983 && TREE_THIS_VOLATILE (current_function_decl
));
4985 return_used_this_function
= 1;
4990 /* If this function was declared non-returning, and we have found a tail
4991 call, then we have to trust that the called function won't return. */
4992 if (! really_return
)
4995 /* Otherwise, trap an attempted return by aborting. */
4997 ops
[1] = gen_rtx_SYMBOL_REF (Pmode
, "abort");
4998 assemble_external_libcall (ops
[1]);
4999 output_asm_insn (reverse
? "bl%D0\t%a1" : "bl%d0\t%a1", ops
);
5003 if (current_function_calls_alloca
&& ! really_return
)
5006 for (reg
= 0; reg
<= 10; reg
++)
5007 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5010 if (live_regs
|| (regs_ever_live
[14] && ! lr_save_eliminated
))
5013 if (frame_pointer_needed
)
5018 if (lr_save_eliminated
|| ! regs_ever_live
[14])
5021 if (frame_pointer_needed
)
5023 reverse
? "ldm%?%D0ea\t%|fp, {" : "ldm%?%d0ea\t%|fp, {");
5026 reverse
? "ldm%?%D0fd\t%|sp!, {" : "ldm%?%d0fd\t%|sp!, {");
5028 for (reg
= 0; reg
<= 10; reg
++)
5029 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5031 strcat (instr
, "%|");
5032 strcat (instr
, reg_names
[reg
]);
5034 strcat (instr
, ", ");
5037 if (frame_pointer_needed
)
5039 strcat (instr
, "%|");
5040 strcat (instr
, reg_names
[11]);
5041 strcat (instr
, ", ");
5042 strcat (instr
, "%|");
5043 strcat (instr
, reg_names
[13]);
5044 strcat (instr
, ", ");
5045 strcat (instr
, "%|");
5046 strcat (instr
, TARGET_THUMB_INTERWORK
|| (! really_return
)
5047 ? reg_names
[14] : reg_names
[15] );
5051 strcat (instr
, "%|");
5052 if (TARGET_THUMB_INTERWORK
&& really_return
)
5053 strcat (instr
, reg_names
[12]);
5055 strcat (instr
, really_return
? reg_names
[15] : reg_names
[14]);
5057 strcat (instr
, (TARGET_APCS_32
|| !really_return
) ? "}" : "}^");
5058 output_asm_insn (instr
, &operand
);
5060 if (TARGET_THUMB_INTERWORK
&& really_return
)
5062 strcpy (instr
, "bx%?");
5063 strcat (instr
, reverse
? "%D0" : "%d0");
5064 strcat (instr
, "\t%|");
5065 strcat (instr
, frame_pointer_needed
? "lr" : "ip");
5067 output_asm_insn (instr
, & operand
);
5070 else if (really_return
)
5072 if (TARGET_THUMB_INTERWORK
)
5073 sprintf (instr
, "bx%%?%%%s0\t%%|lr", reverse
? "D" : "d");
5075 sprintf (instr
, "mov%%?%%%s0%s\t%%|pc, %%|lr",
5076 reverse
? "D" : "d", TARGET_APCS_32
? "" : "s");
5078 output_asm_insn (instr
, & operand
);
5084 /* Return nonzero if optimizing and the current function is volatile.
5085 Such functions never return, and many memory cycles can be saved
5086 by not storing register values that will never be needed again.
5087 This optimization was added to speed up context switching in a
5088 kernel application. */
5091 arm_volatile_func ()
5093 return (optimize
> 0 && TREE_THIS_VOLATILE (current_function_decl
));
5096 /* The amount of stack adjustment that happens here, in output_return and in
5097 output_epilogue must be exactly the same as was calculated during reload,
5098 or things will point to the wrong place. The only time we can safely
5099 ignore this constraint is when a function has no arguments on the stack,
5100 no stack frame requirement and no live registers execpt for `lr'. If we
5101 can guarantee that by making all function calls into tail calls and that
5102 lr is not clobbered in any other way, then there is no need to push lr
5106 output_func_prologue (f
, frame_size
)
5110 int reg
, live_regs_mask
= 0;
5111 int volatile_func
= (optimize
> 0
5112 && TREE_THIS_VOLATILE (current_function_decl
));
5114 /* Nonzero if we must stuff some register arguments onto the stack as if
5115 they were passed there. */
5116 int store_arg_regs
= 0;
5118 if (arm_ccfsm_state
|| arm_target_insn
)
5119 abort (); /* Sanity check */
5121 if (arm_naked_function_p (current_function_decl
))
5124 return_used_this_function
= 0;
5125 lr_save_eliminated
= 0;
5127 fprintf (f
, "\t%s args = %d, pretend = %d, frame = %d\n",
5128 ASM_COMMENT_START
, current_function_args_size
,
5129 current_function_pretend_args_size
, frame_size
);
5130 fprintf (f
, "\t%s frame_needed = %d, current_function_anonymous_args = %d\n",
5131 ASM_COMMENT_START
, frame_pointer_needed
,
5132 current_function_anonymous_args
);
5135 fprintf (f
, "\t%s Volatile function.\n", ASM_COMMENT_START
);
5137 if (current_function_anonymous_args
&& current_function_pretend_args_size
)
5140 for (reg
= 0; reg
<= 10; reg
++)
5141 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5142 live_regs_mask
|= (1 << reg
);
5144 if (frame_pointer_needed
)
5145 live_regs_mask
|= 0xD800;
5146 else if (regs_ever_live
[14])
5148 if (! current_function_args_size
5149 && ! function_really_clobbers_lr (get_insns ()))
5150 lr_save_eliminated
= 1;
5152 live_regs_mask
|= 0x4000;
5157 /* if a di mode load/store multiple is used, and the base register
5158 is r3, then r4 can become an ever live register without lr
5159 doing so, in this case we need to push lr as well, or we
5160 will fail to get a proper return. */
5162 live_regs_mask
|= 0x4000;
5163 lr_save_eliminated
= 0;
5167 if (lr_save_eliminated
)
5168 fprintf (f
,"\t%s I don't think this function clobbers lr\n",
5171 #ifdef AOF_ASSEMBLER
5173 fprintf (f
, "\tmov\t%sip, %s%s\n", REGISTER_PREFIX
, REGISTER_PREFIX
,
5174 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
5180 output_func_epilogue (f
, frame_size
)
5184 int reg
, live_regs_mask
= 0;
5185 /* If we need this then it will always be at least this much */
5186 int floats_offset
= 12;
5188 int volatile_func
= (optimize
> 0
5189 && TREE_THIS_VOLATILE (current_function_decl
));
5191 if (use_return_insn (FALSE
) && return_used_this_function
)
5193 if ((frame_size
+ current_function_outgoing_args_size
) != 0
5194 && !(frame_pointer_needed
&& TARGET_APCS
))
5199 /* Naked functions don't have epilogues. */
5200 if (arm_naked_function_p (current_function_decl
))
5203 /* A volatile function should never return. Call abort. */
5204 if (TARGET_ABORT_NORETURN
&& volatile_func
)
5206 rtx op
= gen_rtx_SYMBOL_REF (Pmode
, "abort");
5207 assemble_external_libcall (op
);
5208 output_asm_insn ("bl\t%a0", &op
);
5212 for (reg
= 0; reg
<= 10; reg
++)
5213 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5215 live_regs_mask
|= (1 << reg
);
5219 if (frame_pointer_needed
)
5221 if (arm_fpu_arch
== FP_SOFT2
)
5223 for (reg
= 23; reg
> 15; reg
--)
5224 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5226 floats_offset
+= 12;
5227 fprintf (f
, "\tldfe\t%s%s, [%sfp, #-%d]\n", REGISTER_PREFIX
,
5228 reg_names
[reg
], REGISTER_PREFIX
, floats_offset
);
5235 for (reg
= 23; reg
> 15; reg
--)
5237 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5239 floats_offset
+= 12;
5240 /* We can't unstack more than four registers at once */
5241 if (start_reg
- reg
== 3)
5243 fprintf (f
, "\tlfm\t%s%s, 4, [%sfp, #-%d]\n",
5244 REGISTER_PREFIX
, reg_names
[reg
],
5245 REGISTER_PREFIX
, floats_offset
);
5246 start_reg
= reg
- 1;
5251 if (reg
!= start_reg
)
5252 fprintf (f
, "\tlfm\t%s%s, %d, [%sfp, #-%d]\n",
5253 REGISTER_PREFIX
, reg_names
[reg
+ 1],
5254 start_reg
- reg
, REGISTER_PREFIX
, floats_offset
);
5256 start_reg
= reg
- 1;
5260 /* Just in case the last register checked also needs unstacking. */
5261 if (reg
!= start_reg
)
5262 fprintf (f
, "\tlfm\t%s%s, %d, [%sfp, #-%d]\n",
5263 REGISTER_PREFIX
, reg_names
[reg
+ 1],
5264 start_reg
- reg
, REGISTER_PREFIX
, floats_offset
);
5267 if (TARGET_THUMB_INTERWORK
)
5269 live_regs_mask
|= 0x6800;
5270 print_multi_reg (f
, "ldmea\t%sfp", live_regs_mask
, FALSE
);
5271 fprintf (f
, "\tbx\t%slr\n", REGISTER_PREFIX
);
5275 live_regs_mask
|= 0xA800;
5276 print_multi_reg (f
, "ldmea\t%sfp", live_regs_mask
,
5277 TARGET_APCS_32
? FALSE
: TRUE
);
5282 /* Restore stack pointer if necessary. */
5283 if (frame_size
+ current_function_outgoing_args_size
!= 0)
5285 operands
[0] = operands
[1] = stack_pointer_rtx
;
5286 operands
[2] = GEN_INT (frame_size
5287 + current_function_outgoing_args_size
);
5288 output_add_immediate (operands
);
5291 if (arm_fpu_arch
== FP_SOFT2
)
5293 for (reg
= 16; reg
< 24; reg
++)
5294 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5295 fprintf (f
, "\tldfe\t%s%s, [%ssp], #12\n", REGISTER_PREFIX
,
5296 reg_names
[reg
], REGISTER_PREFIX
);
5302 for (reg
= 16; reg
< 24; reg
++)
5304 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5306 if (reg
- start_reg
== 3)
5308 fprintf (f
, "\tlfmfd\t%s%s, 4, [%ssp]!\n",
5309 REGISTER_PREFIX
, reg_names
[start_reg
],
5311 start_reg
= reg
+ 1;
5316 if (reg
!= start_reg
)
5317 fprintf (f
, "\tlfmfd\t%s%s, %d, [%ssp]!\n",
5318 REGISTER_PREFIX
, reg_names
[start_reg
],
5319 reg
- start_reg
, REGISTER_PREFIX
);
5321 start_reg
= reg
+ 1;
5325 /* Just in case the last register checked also needs unstacking. */
5326 if (reg
!= start_reg
)
5327 fprintf (f
, "\tlfmfd\t%s%s, %d, [%ssp]!\n",
5328 REGISTER_PREFIX
, reg_names
[start_reg
],
5329 reg
- start_reg
, REGISTER_PREFIX
);
5332 if (current_function_pretend_args_size
== 0 && regs_ever_live
[14])
5334 if (TARGET_THUMB_INTERWORK
)
5336 if (! lr_save_eliminated
)
5337 live_regs_mask
|= 0x4000;
5339 if (live_regs_mask
!= 0)
5340 print_multi_reg (f
, "ldmfd\t%ssp!", live_regs_mask
, FALSE
);
5342 fprintf (f
, "\tbx\t%slr\n", REGISTER_PREFIX
);
5344 else if (lr_save_eliminated
)
5345 fprintf (f
, (TARGET_APCS_32
? "\tmov\t%spc, %slr\n"
5346 : "\tmovs\t%spc, %slr\n"),
5347 REGISTER_PREFIX
, REGISTER_PREFIX
, f
);
5349 print_multi_reg (f
, "ldmfd\t%ssp!", live_regs_mask
| 0x8000,
5350 TARGET_APCS_32
? FALSE
: TRUE
);
5354 if (live_regs_mask
|| regs_ever_live
[14])
5356 /* Restore the integer regs, and the return address into lr */
5357 if (! lr_save_eliminated
)
5358 live_regs_mask
|= 0x4000;
5360 if (live_regs_mask
!= 0)
5361 print_multi_reg (f
, "ldmfd\t%ssp!", live_regs_mask
, FALSE
);
5364 if (current_function_pretend_args_size
)
5366 /* Unwind the pre-pushed regs */
5367 operands
[0] = operands
[1] = stack_pointer_rtx
;
5368 operands
[2] = GEN_INT (current_function_pretend_args_size
);
5369 output_add_immediate (operands
);
5371 /* And finally, go home */
5372 if (TARGET_THUMB_INTERWORK
)
5373 fprintf (f
, "\tbx\t%slr\n", REGISTER_PREFIX
);
5374 else if (TARGET_APCS_32
)
5375 fprintf (f
, "\tmov\t%spc, %slr\n", REGISTER_PREFIX
, REGISTER_PREFIX
);
5377 fprintf (f
, "\tmovs\t%spc, %slr\n", REGISTER_PREFIX
, REGISTER_PREFIX
);
5383 current_function_anonymous_args
= 0;
5387 emit_multi_reg_push (mask
)
5394 for (i
= 0; i
< 16; i
++)
5395 if (mask
& (1 << i
))
5398 if (num_regs
== 0 || num_regs
> 16)
5401 par
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (num_regs
));
5403 for (i
= 0; i
< 16; i
++)
5405 if (mask
& (1 << i
))
5408 = gen_rtx_SET (VOIDmode
,
5409 gen_rtx_MEM (BLKmode
,
5410 gen_rtx_PRE_DEC (BLKmode
,
5411 stack_pointer_rtx
)),
5412 gen_rtx_UNSPEC (BLKmode
,
5414 gen_rtx_REG (SImode
, i
)),
5420 for (j
= 1, i
++; j
< num_regs
; i
++)
5422 if (mask
& (1 << i
))
5425 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, i
));
5434 emit_sfm (base_reg
, count
)
5441 par
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (count
));
5444 = gen_rtx_SET (VOIDmode
,
5445 gen_rtx_MEM (BLKmode
,
5446 gen_rtx_PRE_DEC (BLKmode
, stack_pointer_rtx
)),
5447 gen_rtx_UNSPEC (BLKmode
,
5448 gen_rtvec (1, gen_rtx_REG (XFmode
,
5451 for (i
= 1; i
< count
; i
++)
5452 XVECEXP (par
, 0, i
) = gen_rtx_USE (VOIDmode
,
5453 gen_rtx_REG (XFmode
, base_reg
++));
5459 arm_expand_prologue ()
5462 rtx amount
= GEN_INT (-(get_frame_size ()
5463 + current_function_outgoing_args_size
));
5464 int live_regs_mask
= 0;
5465 int store_arg_regs
= 0;
5466 int volatile_func
= (optimize
> 0
5467 && TREE_THIS_VOLATILE (current_function_decl
));
5469 /* Naked functions don't have prologues. */
5470 if (arm_naked_function_p (current_function_decl
))
5473 if (current_function_anonymous_args
&& current_function_pretend_args_size
)
5476 if (! volatile_func
)
5477 for (reg
= 0; reg
<= 10; reg
++)
5478 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5479 live_regs_mask
|= 1 << reg
;
5481 if (! volatile_func
&& regs_ever_live
[14])
5482 live_regs_mask
|= 0x4000;
5484 if (frame_pointer_needed
)
5486 live_regs_mask
|= 0xD800;
5487 emit_insn (gen_movsi (gen_rtx_REG (SImode
, 12),
5488 stack_pointer_rtx
));
5491 if (current_function_pretend_args_size
)
5494 emit_multi_reg_push ((0xf0 >> (current_function_pretend_args_size
/ 4))
5497 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
5498 GEN_INT (-current_function_pretend_args_size
)));
5503 /* If we have to push any regs, then we must push lr as well, or
5504 we won't get a proper return. */
5505 live_regs_mask
|= 0x4000;
5506 emit_multi_reg_push (live_regs_mask
);
5509 /* For now the integer regs are still pushed in output_func_epilogue (). */
5511 if (! volatile_func
)
5513 if (arm_fpu_arch
== FP_SOFT2
)
5515 for (reg
= 23; reg
> 15; reg
--)
5516 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5517 emit_insn (gen_rtx_SET
5519 gen_rtx_MEM (XFmode
,
5520 gen_rtx_PRE_DEC (XFmode
,
5521 stack_pointer_rtx
)),
5522 gen_rtx_REG (XFmode
, reg
)));
5528 for (reg
= 23; reg
> 15; reg
--)
5530 if (regs_ever_live
[reg
] && ! call_used_regs
[reg
])
5532 if (start_reg
- reg
== 3)
5535 start_reg
= reg
- 1;
5540 if (start_reg
!= reg
)
5541 emit_sfm (reg
+ 1, start_reg
- reg
);
5542 start_reg
= reg
- 1;
5546 if (start_reg
!= reg
)
5547 emit_sfm (reg
+ 1, start_reg
- reg
);
5551 if (frame_pointer_needed
)
5552 emit_insn (gen_addsi3 (hard_frame_pointer_rtx
, gen_rtx_REG (SImode
, 12),
5554 (-(4 + current_function_pretend_args_size
)))));
5556 if (amount
!= const0_rtx
)
5558 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
, amount
));
5559 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
5560 gen_rtx_MEM (BLKmode
, stack_pointer_rtx
)));
5563 /* If we are profiling, make sure no instructions are scheduled before
5564 the call to mcount. Similarly if the user has requested no
5565 scheduling in the prolog. */
5566 if (profile_flag
|| profile_block_flag
|| TARGET_NO_SCHED_PRO
)
5567 emit_insn (gen_blockage ());
5571 /* If CODE is 'd', then the X is a condition operand and the instruction
5572 should only be executed if the condition is true.
5573 if CODE is 'D', then the X is a condition operand and the instruction
5574 should only be executed if the condition is false: however, if the mode
5575 of the comparison is CCFPEmode, then always execute the instruction -- we
5576 do this because in these circumstances !GE does not necessarily imply LT;
5577 in these cases the instruction pattern will take care to make sure that
5578 an instruction containing %d will follow, thereby undoing the effects of
5579 doing this instruction unconditionally.
5580 If CODE is 'N' then X is a floating point operand that must be negated
5582 If CODE is 'B' then output a bitwise inverted value of X (a const int).
5583 If X is a REG and CODE is `M', output a ldm/stm style multi-reg. */
5586 arm_print_operand (stream
, x
, code
)
5594 fputs (ASM_COMMENT_START
, stream
);
5598 fputs (REGISTER_PREFIX
, stream
);
5602 if (arm_ccfsm_state
== 3 || arm_ccfsm_state
== 4)
5603 fputs (arm_condition_codes
[arm_current_cc
], stream
);
5609 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
5610 r
= REAL_VALUE_NEGATE (r
);
5611 fprintf (stream
, "%s", fp_const_from_val (&r
));
5616 if (GET_CODE (x
) == CONST_INT
)
5618 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
5623 ARM_SIGN_EXTEND (~ INTVAL (x
)));
5627 output_addr_const (stream
, x
);
5632 fprintf (stream
, "%s", arithmetic_instr (x
, 1));
5636 fprintf (stream
, "%s", arithmetic_instr (x
, 0));
5642 char *shift
= shift_op (x
, &val
);
5646 fprintf (stream
, ", %s ", shift_op (x
, &val
));
5648 arm_print_operand (stream
, XEXP (x
, 1), 0);
5651 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
5664 fputs (REGISTER_PREFIX
, stream
);
5665 fputs (reg_names
[REGNO (x
) + (WORDS_BIG_ENDIAN
? 1 : 0)], stream
);
5671 fputs (REGISTER_PREFIX
, stream
);
5672 fputs (reg_names
[REGNO (x
) + (WORDS_BIG_ENDIAN
? 0 : 1)], stream
);
5676 fputs (REGISTER_PREFIX
, stream
);
5677 if (GET_CODE (XEXP (x
, 0)) == REG
)
5678 fputs (reg_names
[REGNO (XEXP (x
, 0))], stream
);
5680 fputs (reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))], stream
);
5684 fprintf (stream
, "{%s%s-%s%s}", REGISTER_PREFIX
, reg_names
[REGNO (x
)],
5685 REGISTER_PREFIX
, reg_names
[REGNO (x
) - 1
5686 + ((GET_MODE_SIZE (GET_MODE (x
))
5687 + GET_MODE_SIZE (SImode
) - 1)
5688 / GET_MODE_SIZE (SImode
))]);
5693 fputs (arm_condition_codes
[get_arm_condition_code (x
)],
5699 fputs (arm_condition_codes
[ARM_INVERSE_CONDITION_CODE
5700 (get_arm_condition_code (x
))],
5708 if (GET_CODE (x
) == REG
)
5710 fputs (REGISTER_PREFIX
, stream
);
5711 fputs (reg_names
[REGNO (x
)], stream
);
5713 else if (GET_CODE (x
) == MEM
)
5715 output_memory_reference_mode
= GET_MODE (x
);
5716 output_address (XEXP (x
, 0));
5718 else if (GET_CODE (x
) == CONST_DOUBLE
)
5719 fprintf (stream
, "#%s", fp_immediate_constant (x
));
5720 else if (GET_CODE (x
) == NEG
)
5721 abort (); /* This should never happen now. */
5724 fputc ('#', stream
);
5725 output_addr_const (stream
, x
);
5731 /* A finite state machine takes care of noticing whether or not instructions
5732 can be conditionally executed, and thus decrease execution time and code
5733 size by deleting branch instructions. The fsm is controlled by
5734 final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE. */
5736 /* The state of the fsm controlling condition codes are:
5737 0: normal, do nothing special
5738 1: make ASM_OUTPUT_OPCODE not output this instruction
5739 2: make ASM_OUTPUT_OPCODE not output this instruction
5740 3: make instructions conditional
5741 4: make instructions conditional
5743 State transitions (state->state by whom under condition):
5744 0 -> 1 final_prescan_insn if the `target' is a label
5745 0 -> 2 final_prescan_insn if the `target' is an unconditional branch
5746 1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
5747 2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
5748 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL if the `target' label is reached
5749 (the target label has CODE_LABEL_NUMBER equal to arm_target_label).
5750 4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
5751 (the target insn is arm_target_insn).
5753 If the jump clobbers the conditions then we use states 2 and 4.
5755 A similar thing can be done with conditional return insns.
5757 XXX In case the `target' is an unconditional branch, this conditionalising
5758 of the instructions always reduces code size, but not always execution
5759 time. But then, I want to reduce the code size to somewhere near what
5760 /bin/cc produces. */
5762 /* Returns the index of the ARM condition code string in
5763 `arm_condition_codes'. COMPARISON should be an rtx like
5764 `(eq (...) (...))'. */
5766 static enum arm_cond_code
5767 get_arm_condition_code (comparison
)
5770 enum machine_mode mode
= GET_MODE (XEXP (comparison
, 0));
5772 register enum rtx_code comp_code
= GET_CODE (comparison
);
5774 if (GET_MODE_CLASS (mode
) != MODE_CC
)
5775 mode
= SELECT_CC_MODE (comp_code
, XEXP (comparison
, 0),
5776 XEXP (comparison
, 1));
5780 case CC_DNEmode
: code
= ARM_NE
; goto dominance
;
5781 case CC_DEQmode
: code
= ARM_EQ
; goto dominance
;
5782 case CC_DGEmode
: code
= ARM_GE
; goto dominance
;
5783 case CC_DGTmode
: code
= ARM_GT
; goto dominance
;
5784 case CC_DLEmode
: code
= ARM_LE
; goto dominance
;
5785 case CC_DLTmode
: code
= ARM_LT
; goto dominance
;
5786 case CC_DGEUmode
: code
= ARM_CS
; goto dominance
;
5787 case CC_DGTUmode
: code
= ARM_HI
; goto dominance
;
5788 case CC_DLEUmode
: code
= ARM_LS
; goto dominance
;
5789 case CC_DLTUmode
: code
= ARM_CC
;
5792 if (comp_code
!= EQ
&& comp_code
!= NE
)
5795 if (comp_code
== EQ
)
5796 return ARM_INVERSE_CONDITION_CODE (code
);
5802 case NE
: return ARM_NE
;
5803 case EQ
: return ARM_EQ
;
5804 case GE
: return ARM_PL
;
5805 case LT
: return ARM_MI
;
5813 case NE
: return ARM_NE
;
5814 case EQ
: return ARM_EQ
;
5821 case GE
: return ARM_GE
;
5822 case GT
: return ARM_GT
;
5823 case LE
: return ARM_LS
;
5824 case LT
: return ARM_MI
;
5831 case NE
: return ARM_NE
;
5832 case EQ
: return ARM_EQ
;
5833 case GE
: return ARM_LE
;
5834 case GT
: return ARM_LT
;
5835 case LE
: return ARM_GE
;
5836 case LT
: return ARM_GT
;
5837 case GEU
: return ARM_LS
;
5838 case GTU
: return ARM_CC
;
5839 case LEU
: return ARM_CS
;
5840 case LTU
: return ARM_HI
;
5847 case LTU
: return ARM_CS
;
5848 case GEU
: return ARM_CC
;
5855 case NE
: return ARM_NE
;
5856 case EQ
: return ARM_EQ
;
5857 case GE
: return ARM_GE
;
5858 case GT
: return ARM_GT
;
5859 case LE
: return ARM_LE
;
5860 case LT
: return ARM_LT
;
5861 case GEU
: return ARM_CS
;
5862 case GTU
: return ARM_HI
;
5863 case LEU
: return ARM_LS
;
5864 case LTU
: return ARM_CC
;
5876 final_prescan_insn (insn
, opvec
, noperands
)
5881 /* BODY will hold the body of INSN. */
5882 register rtx body
= PATTERN (insn
);
5884 /* This will be 1 if trying to repeat the trick, and things need to be
5885 reversed if it appears to fail. */
5888 /* JUMP_CLOBBERS will be one implies that the conditions if a branch is
5889 taken are clobbered, even if the rtl suggests otherwise. It also
5890 means that we have to grub around within the jump expression to find
5891 out what the conditions are when the jump isn't taken. */
5892 int jump_clobbers
= 0;
5894 /* If we start with a return insn, we only succeed if we find another one. */
5895 int seeking_return
= 0;
5897 /* START_INSN will hold the insn from where we start looking. This is the
5898 first insn after the following code_label if REVERSE is true. */
5899 rtx start_insn
= insn
;
5901 /* If in state 4, check if the target branch is reached, in order to
5902 change back to state 0. */
5903 if (arm_ccfsm_state
== 4)
5905 if (insn
== arm_target_insn
)
5907 arm_target_insn
= NULL
;
5908 arm_ccfsm_state
= 0;
5913 /* If in state 3, it is possible to repeat the trick, if this insn is an
5914 unconditional branch to a label, and immediately following this branch
5915 is the previous target label which is only used once, and the label this
5916 branch jumps to is not too far off. */
5917 if (arm_ccfsm_state
== 3)
5919 if (simplejump_p (insn
))
5921 start_insn
= next_nonnote_insn (start_insn
);
5922 if (GET_CODE (start_insn
) == BARRIER
)
5924 /* XXX Isn't this always a barrier? */
5925 start_insn
= next_nonnote_insn (start_insn
);
5927 if (GET_CODE (start_insn
) == CODE_LABEL
5928 && CODE_LABEL_NUMBER (start_insn
) == arm_target_label
5929 && LABEL_NUSES (start_insn
) == 1)
5934 else if (GET_CODE (body
) == RETURN
)
5936 start_insn
= next_nonnote_insn (start_insn
);
5937 if (GET_CODE (start_insn
) == BARRIER
)
5938 start_insn
= next_nonnote_insn (start_insn
);
5939 if (GET_CODE (start_insn
) == CODE_LABEL
5940 && CODE_LABEL_NUMBER (start_insn
) == arm_target_label
5941 && LABEL_NUSES (start_insn
) == 1)
5953 if (arm_ccfsm_state
!= 0 && !reverse
)
5955 if (GET_CODE (insn
) != JUMP_INSN
)
5958 /* This jump might be paralleled with a clobber of the condition codes
5959 the jump should always come first */
5960 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
5961 body
= XVECEXP (body
, 0, 0);
5964 /* If this is a conditional return then we don't want to know */
5965 if (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
5966 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
5967 && (GET_CODE (XEXP (SET_SRC (body
), 1)) == RETURN
5968 || GET_CODE (XEXP (SET_SRC (body
), 2)) == RETURN
))
5973 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
5974 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
5977 int fail
= FALSE
, succeed
= FALSE
;
5978 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
5979 int then_not_else
= TRUE
;
5980 rtx this_insn
= start_insn
, label
= 0;
5982 if (get_attr_conds (insn
) == CONDS_JUMP_CLOB
)
5984 /* The code below is wrong for these, and I haven't time to
5985 fix it now. So we just do the safe thing and return. This
5986 whole function needs re-writing anyway. */
5991 /* Register the insn jumped to. */
5994 if (!seeking_return
)
5995 label
= XEXP (SET_SRC (body
), 0);
5997 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
5998 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
5999 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
6001 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
6002 then_not_else
= FALSE
;
6004 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == RETURN
)
6006 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == RETURN
)
6009 then_not_else
= FALSE
;
6014 /* See how many insns this branch skips, and what kind of insns. If all
6015 insns are okay, and the label or unconditional branch to the same
6016 label is not too far away, succeed. */
6017 for (insns_skipped
= 0;
6018 !fail
&& !succeed
&& insns_skipped
++ < max_insns_skipped
;)
6022 this_insn
= next_nonnote_insn (this_insn
);
6026 switch (GET_CODE (this_insn
))
6029 /* Succeed if it is the target label, otherwise fail since
6030 control falls in from somewhere else. */
6031 if (this_insn
== label
)
6035 arm_ccfsm_state
= 2;
6036 this_insn
= next_nonnote_insn (this_insn
);
6039 arm_ccfsm_state
= 1;
6047 /* Succeed if the following insn is the target label.
6049 If return insns are used then the last insn in a function
6050 will be a barrier. */
6051 this_insn
= next_nonnote_insn (this_insn
);
6052 if (this_insn
&& this_insn
== label
)
6056 arm_ccfsm_state
= 2;
6057 this_insn
= next_nonnote_insn (this_insn
);
6060 arm_ccfsm_state
= 1;
6068 /* If using 32-bit addresses the cc is not preserved over
6072 /* Succeed if the following insn is the target label,
6073 or if the following two insns are a barrier and
6074 the target label. */
6075 this_insn
= next_nonnote_insn (this_insn
);
6076 if (this_insn
&& GET_CODE (this_insn
) == BARRIER
)
6077 this_insn
= next_nonnote_insn (this_insn
);
6079 if (this_insn
&& this_insn
== label
6080 && insns_skipped
< max_insns_skipped
)
6084 arm_ccfsm_state
= 2;
6085 this_insn
= next_nonnote_insn (this_insn
);
6088 arm_ccfsm_state
= 1;
6097 /* If this is an unconditional branch to the same label, succeed.
6098 If it is to another label, do nothing. If it is conditional,
6100 /* XXX Probably, the tests for SET and the PC are unnecessary. */
6102 scanbody
= PATTERN (this_insn
);
6103 if (GET_CODE (scanbody
) == SET
6104 && GET_CODE (SET_DEST (scanbody
)) == PC
)
6106 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
6107 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
6109 arm_ccfsm_state
= 2;
6112 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
6115 /* Fail if a conditional return is undesirable (eg on a
6116 StrongARM), but still allow this if optimizing for size. */
6117 else if (GET_CODE (scanbody
) == RETURN
6118 && ! use_return_insn (TRUE
)
6121 else if (GET_CODE (scanbody
) == RETURN
6124 arm_ccfsm_state
= 2;
6127 else if (GET_CODE (scanbody
) == PARALLEL
)
6129 switch (get_attr_conds (this_insn
))
6141 /* Instructions using or affecting the condition codes make it
6143 scanbody
= PATTERN (this_insn
);
6144 if (! (GET_CODE (scanbody
) == SET
6145 || GET_CODE (scanbody
) == PARALLEL
)
6146 || get_attr_conds (this_insn
) != CONDS_NOCOND
)
6156 if ((!seeking_return
) && (arm_ccfsm_state
== 1 || reverse
))
6157 arm_target_label
= CODE_LABEL_NUMBER (label
);
6158 else if (seeking_return
|| arm_ccfsm_state
== 2)
6160 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
6162 this_insn
= next_nonnote_insn (this_insn
);
6163 if (this_insn
&& (GET_CODE (this_insn
) == BARRIER
6164 || GET_CODE (this_insn
) == CODE_LABEL
))
6169 /* Oh, dear! we ran off the end.. give up */
6170 recog (PATTERN (insn
), insn
, NULL_PTR
);
6171 arm_ccfsm_state
= 0;
6172 arm_target_insn
= NULL
;
6175 arm_target_insn
= this_insn
;
6184 get_arm_condition_code (XEXP (XEXP (XEXP (SET_SRC (body
),
6186 if (GET_CODE (XEXP (XEXP (SET_SRC (body
), 0), 0)) == AND
)
6187 arm_current_cc
= ARM_INVERSE_CONDITION_CODE (arm_current_cc
);
6188 if (GET_CODE (XEXP (SET_SRC (body
), 0)) == NE
)
6189 arm_current_cc
= ARM_INVERSE_CONDITION_CODE (arm_current_cc
);
6193 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
6196 arm_current_cc
= get_arm_condition_code (XEXP (SET_SRC (body
),
6200 if (reverse
|| then_not_else
)
6201 arm_current_cc
= ARM_INVERSE_CONDITION_CODE (arm_current_cc
);
6203 /* restore recog_operand (getting the attributes of other insns can
6204 destroy this array, but final.c assumes that it remains intact
6205 across this call; since the insn has been recognized already we
6206 call recog direct). */
6207 recog (PATTERN (insn
), insn
, NULL_PTR
);
6211 #ifdef AOF_ASSEMBLER
6212 /* Special functions only needed when producing AOF syntax assembler. */
6214 rtx aof_pic_label
= NULL_RTX
;
6217 struct pic_chain
*next
;
6221 static struct pic_chain
*aof_pic_chain
= NULL
;
6227 struct pic_chain
**chainp
;
6230 if (aof_pic_label
== NULL_RTX
)
6232 /* This needs to persist throughout the compilation. */
6233 end_temporary_allocation ();
6234 aof_pic_label
= gen_rtx_SYMBOL_REF (Pmode
, "x$adcons");
6235 resume_temporary_allocation ();
6238 for (offset
= 0, chainp
= &aof_pic_chain
; *chainp
;
6239 offset
+= 4, chainp
= &(*chainp
)->next
)
6240 if ((*chainp
)->symname
== XSTR (x
, 0))
6241 return plus_constant (aof_pic_label
, offset
);
6243 *chainp
= (struct pic_chain
*) xmalloc (sizeof (struct pic_chain
));
6244 (*chainp
)->next
= NULL
;
6245 (*chainp
)->symname
= XSTR (x
, 0);
6246 return plus_constant (aof_pic_label
, offset
);
6250 aof_dump_pic_table (f
)
6253 struct pic_chain
*chain
;
6255 if (aof_pic_chain
== NULL
)
6258 fprintf (f
, "\tAREA |%s$$adcons|, BASED %s%s\n",
6259 reg_names
[PIC_OFFSET_TABLE_REGNUM
], REGISTER_PREFIX
,
6260 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
6261 fputs ("|x$adcons|\n", f
);
6263 for (chain
= aof_pic_chain
; chain
; chain
= chain
->next
)
6265 fputs ("\tDCD\t", f
);
6266 assemble_name (f
, chain
->symname
);
6271 int arm_text_section_count
= 1;
6276 static char buf
[100];
6277 sprintf (buf
, "\tAREA |C$$code%d|, CODE, READONLY",
6278 arm_text_section_count
++);
6280 strcat (buf
, ", PIC, REENTRANT");
6284 static int arm_data_section_count
= 1;
6289 static char buf
[100];
6290 sprintf (buf
, "\tAREA |C$$data%d|, DATA", arm_data_section_count
++);
6294 /* The AOF assembler is religiously strict about declarations of
6295 imported and exported symbols, so that it is impossible to declare
6296 a function as imported near the beginning of the file, and then to
6297 export it later on. It is, however, possible to delay the decision
6298 until all the functions in the file have been compiled. To get
6299 around this, we maintain a list of the imports and exports, and
6300 delete from it any that are subsequently defined. At the end of
6301 compilation we spit the remainder of the list out before the END
6306 struct import
*next
;
6310 static struct import
*imports_list
= NULL
;
6313 aof_add_import (name
)
6318 for (new = imports_list
; new; new = new->next
)
6319 if (new->name
== name
)
6322 new = (struct import
*) xmalloc (sizeof (struct import
));
6323 new->next
= imports_list
;
6329 aof_delete_import (name
)
6332 struct import
**old
;
6334 for (old
= &imports_list
; *old
; old
= & (*old
)->next
)
6336 if ((*old
)->name
== name
)
6338 *old
= (*old
)->next
;
6344 int arm_main_function
= 0;
6347 aof_dump_imports (f
)
6350 /* The AOF assembler needs this to cause the startup code to be extracted
6351 from the library. Brining in __main causes the whole thing to work
6353 if (arm_main_function
)
6356 fputs ("\tIMPORT __main\n", f
);
6357 fputs ("\tDCD __main\n", f
);
6360 /* Now dump the remaining imports. */
6361 while (imports_list
)
6363 fprintf (f
, "\tIMPORT\t");
6364 assemble_name (f
, imports_list
->name
);
6366 imports_list
= imports_list
->next
;
6369 #endif /* AOF_ASSEMBLER */