• Main Page
  • Modules
  • Data Types
  • Files

osprey-gcc/gcc/config/frv/frv.c

Go to the documentation of this file.
00001 /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
00002    Free Software Foundation, Inc.
00003    Contributed by Red Hat, Inc.
00004 
00005 This file is part of GCC.
00006 
00007 GCC is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GCC is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GCC; see the file COPYING.  If not, write to
00019 the Free Software Foundation, 59 Temple Place - Suite 330,
00020 Boston, MA 02111-1307, USA.  */
00021 
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "rtl.h"
00027 #include "tree.h"
00028 #include "regs.h"
00029 #include "hard-reg-set.h"
00030 #include "real.h"
00031 #include "insn-config.h"
00032 #include "conditions.h"
00033 #include "insn-flags.h"
00034 #include "output.h"
00035 #include "insn-attr.h"
00036 #include "flags.h"
00037 #include "recog.h"
00038 #include "reload.h"
00039 #include "expr.h"
00040 #include "obstack.h"
00041 #include "except.h"
00042 #include "function.h"
00043 #include "optabs.h"
00044 #include "toplev.h"
00045 #include "basic-block.h"
00046 #include "tm_p.h"
00047 #include "ggc.h"
00048 #include <ctype.h>
00049 #include "target.h"
00050 #include "target-def.h"
00051 #include "targhooks.h"
00052 #include "integrate.h"
00053 #include "langhooks.h"
00054 
00055 #ifndef FRV_INLINE
00056 #define FRV_INLINE inline
00057 #endif
00058 
00059 /* The maximum number of distinct NOP patterns.  There are three:
00060    nop, fnop and mnop.  */
00061 #define NUM_NOP_PATTERNS 3
00062 
00063 /* Classification of instructions and units: integer, floating-point/media,
00064    branch and control.  */
00065 enum frv_insn_group { GROUP_I, GROUP_FM, GROUP_B, GROUP_C, NUM_GROUPS };
00066 
00067 /* The DFA names of the units, in packet order.  */
00068 static const char *const frv_unit_names[] =
00069 {
00070   "c",
00071   "i0", "f0",
00072   "i1", "f1",
00073   "i2", "f2",
00074   "i3", "f3",
00075   "b0", "b1"
00076 };
00077 
00078 /* The classification of each unit in frv_unit_names[].  */
00079 static const enum frv_insn_group frv_unit_groups[ARRAY_SIZE (frv_unit_names)] =
00080 {
00081   GROUP_C,
00082   GROUP_I, GROUP_FM,
00083   GROUP_I, GROUP_FM,
00084   GROUP_I, GROUP_FM,
00085   GROUP_I, GROUP_FM,
00086   GROUP_B, GROUP_B
00087 };
00088 
00089 /* Return the DFA unit code associated with the Nth unit of integer
00090    or floating-point group GROUP,  */
00091 #define NTH_UNIT(GROUP, N) frv_unit_codes[(GROUP) + (N) * 2 + 1]
00092 
00093 /* Return the number of integer or floating-point unit UNIT
00094    (1 for I1, 2 for F2, etc.).  */
00095 #define UNIT_NUMBER(UNIT) (((UNIT) - 1) / 2)
00096 
00097 /* The DFA unit number for each unit in frv_unit_names[].  */
00098 static int frv_unit_codes[ARRAY_SIZE (frv_unit_names)];
00099 
00100 /* FRV_TYPE_TO_UNIT[T] is the last unit in frv_unit_names[] that can issue
00101    an instruction of type T.  The value is ARRAY_SIZE (frv_unit_names) if
00102    no instruction of type T has been seen.  */
00103 static unsigned int frv_type_to_unit[TYPE_UNKNOWN + 1];
00104 
00105 /* An array of dummy nop INSNs, one for each type of nop that the
00106    target supports.  */
00107 static GTY(()) rtx frv_nops[NUM_NOP_PATTERNS];
00108 
00109 /* The number of nop instructions in frv_nops[].  */
00110 static unsigned int frv_num_nops;
00111 
00112 /* Return true if instruction INSN should be packed with the following
00113    instruction.  */
00114 #define PACKING_FLAG_P(INSN) (GET_MODE (INSN) == TImode)
00115 
00116 /* Set the value of PACKING_FLAG_P(INSN).  */
00117 #define SET_PACKING_FLAG(INSN) PUT_MODE (INSN, TImode)
00118 #define CLEAR_PACKING_FLAG(INSN) PUT_MODE (INSN, VOIDmode)
00119 
00120 /* Loop with REG set to each hard register in rtx X.  */
00121 #define FOR_EACH_REGNO(REG, X)            \
00122   for (REG = REGNO (X);             \
00123        REG < REGNO (X) + HARD_REGNO_NREGS (REGNO (X), GET_MODE (X));  \
00124        REG++)
00125 
00126 /* Information about a relocation unspec.  SYMBOL is the relocation symbol
00127    (a SYMBOL_REF or LABEL_REF), RELOC is the type of relocation and OFFSET
00128    is the constant addend.  */
00129 struct frv_unspec {
00130   rtx symbol;
00131   int reloc;
00132   HOST_WIDE_INT offset;
00133 };
00134 
00135 /* Temporary register allocation support structure.  */
00136 typedef struct frv_tmp_reg_struct
00137   {
00138     HARD_REG_SET regs;    /* possible registers to allocate */
00139     int next_reg[N_REG_CLASSES];  /* next register to allocate per class */
00140   }
00141 frv_tmp_reg_t;
00142 
00143 /* Register state information for VLIW re-packing phase.  */
00144 #define REGSTATE_CC_MASK  0x07  /* Mask to isolate CCn for cond exec */
00145 #define REGSTATE_MODIFIED 0x08  /* reg modified in current VLIW insn */
00146 #define REGSTATE_IF_TRUE  0x10  /* reg modified in cond exec true */
00147 #define REGSTATE_IF_FALSE 0x20  /* reg modified in cond exec false */
00148 
00149 #define REGSTATE_IF_EITHER  (REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)
00150 
00151 typedef unsigned char regstate_t;
00152 
00153 /* Used in frv_frame_accessor_t to indicate the direction of a register-to-
00154    memory move.  */
00155 enum frv_stack_op
00156 {
00157   FRV_LOAD,
00158   FRV_STORE
00159 };
00160 
00161 /* Information required by frv_frame_access.  */
00162 typedef struct
00163 {
00164   /* This field is FRV_LOAD if registers are to be loaded from the stack and
00165      FRV_STORE if they should be stored onto the stack.  FRV_STORE implies
00166      the move is being done by the prologue code while FRV_LOAD implies it
00167      is being done by the epilogue.  */
00168   enum frv_stack_op op;
00169 
00170   /* The base register to use when accessing the stack.  This may be the
00171      frame pointer, stack pointer, or a temporary.  The choice of register
00172      depends on which part of the frame is being accessed and how big the
00173      frame is.  */
00174   rtx base;
00175 
00176   /* The offset of BASE from the bottom of the current frame, in bytes.  */
00177   int base_offset;
00178 } frv_frame_accessor_t;
00179 
00180 /* Define the information needed to generate branch and scc insns.  This is
00181    stored from the compare operation.  */
00182 rtx frv_compare_op0;
00183 rtx frv_compare_op1;
00184 
00185 /* Conditional execution support gathered together in one structure.  */
00186 typedef struct
00187   {
00188     /* Linked list of insns to add if the conditional execution conversion was
00189        successful.  Each link points to an EXPR_LIST which points to the pattern
00190        of the insn to add, and the insn to be inserted before.  */
00191     rtx added_insns_list;
00192 
00193     /* Identify which registers are safe to allocate for if conversions to
00194        conditional execution.  We keep the last allocated register in the
00195        register classes between COND_EXEC statements.  This will mean we allocate
00196        different registers for each different COND_EXEC group if we can.  This
00197        might allow the scheduler to intermix two different COND_EXEC sections.  */
00198     frv_tmp_reg_t tmp_reg;
00199 
00200     /* For nested IFs, identify which CC registers are used outside of setting
00201        via a compare isnsn, and using via a check insn.  This will allow us to
00202        know if we can rewrite the register to use a different register that will
00203        be paired with the CR register controlling the nested IF-THEN blocks.  */
00204     HARD_REG_SET nested_cc_ok_rewrite;
00205 
00206     /* Temporary registers allocated to hold constants during conditional
00207        execution.  */
00208     rtx scratch_regs[FIRST_PSEUDO_REGISTER];
00209 
00210     /* Current number of temp registers available.  */
00211     int cur_scratch_regs;
00212 
00213     /* Number of nested conditional execution blocks.  */
00214     int num_nested_cond_exec;
00215 
00216     /* Map of insns that set up constants in scratch registers.  */
00217     bitmap scratch_insns_bitmap;
00218 
00219     /* Conditional execution test register (CC0..CC7).  */
00220     rtx cr_reg;
00221 
00222     /* Conditional execution compare register that is paired with cr_reg, so that
00223        nested compares can be done.  The csubcc and caddcc instructions don't
00224        have enough bits to specify both a CC register to be set and a CR register
00225        to do the test on, so the same bit number is used for both.  Needless to
00226        say, this is rather inconvenient for GCC.  */
00227     rtx nested_cc_reg;
00228 
00229     /* Extra CR registers used for &&, ||.  */
00230     rtx extra_int_cr;
00231     rtx extra_fp_cr;
00232 
00233     /* Previous CR used in nested if, to make sure we are dealing with the same
00234        nested if as the previous statement.  */
00235     rtx last_nested_if_cr;
00236   }
00237 frv_ifcvt_t;
00238 
00239 static /* GTY(()) */ frv_ifcvt_t frv_ifcvt;
00240 
00241 /* Map register number to smallest register class.  */
00242 enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
00243 
00244 /* Map class letter into register class.  */
00245 enum reg_class reg_class_from_letter[256];
00246 
00247 /* Cached value of frv_stack_info.  */
00248 static frv_stack_t *frv_stack_cache = (frv_stack_t *)0;
00249 
00250 /* -mbranch-cost= support */
00251 const char *frv_branch_cost_string;
00252 int frv_branch_cost_int = DEFAULT_BRANCH_COST;
00253 
00254 /* -mcpu= support */
00255 const char *frv_cpu_string;   /* -mcpu= option */
00256 frv_cpu_t frv_cpu_type = CPU_TYPE;  /* value of -mcpu= */
00257 
00258 /* -mcond-exec-insns= support */
00259 const char *frv_condexec_insns_str;    /* -mcond-exec-insns= option */
00260 int frv_condexec_insns = DEFAULT_CONDEXEC_INSNS; /* value of -mcond-exec-insns*/
00261 
00262 /* -mcond-exec-temps= support */
00263 const char *frv_condexec_temps_str;    /* -mcond-exec-temps= option */
00264 int frv_condexec_temps = DEFAULT_CONDEXEC_TEMPS; /* value of -mcond-exec-temps*/
00265 
00266 /* -msched-lookahead=n */
00267 const char *frv_sched_lookahead_str;   /* -msched-lookahead=n */
00268 int frv_sched_lookahead = 4;     /* -msched-lookahead=n */
00269 
00270 /* Forward references */
00271 static int frv_default_flags_for_cpu    (void);
00272 static int frv_string_begins_with   (tree, const char *);
00273 static FRV_INLINE bool frv_small_data_reloc_p (rtx, int);
00274 static FRV_INLINE bool frv_const_unspec_p (rtx, struct frv_unspec *);
00275 static void frv_print_operand_memory_reference_reg
00276             (FILE *, rtx);
00277 static void frv_print_operand_memory_reference  (FILE *, rtx, int);
00278 static int frv_print_operand_jump_hint    (rtx);
00279 static const char *comparison_string    (enum rtx_code, rtx);
00280 static FRV_INLINE int frv_regno_ok_for_base_p (int, int);
00281 static rtx single_set_pattern     (rtx);
00282 static int frv_function_contains_far_jump (void);
00283 static rtx frv_alloc_temp_reg     (frv_tmp_reg_t *,
00284              enum reg_class,
00285              enum machine_mode,
00286              int, int);
00287 static rtx frv_frame_offset_rtx     (int);
00288 static rtx frv_frame_mem      (enum machine_mode, rtx, int);
00289 static rtx frv_dwarf_store      (rtx, int);
00290 static void frv_frame_insn      (rtx, rtx);
00291 static void frv_frame_access      (frv_frame_accessor_t*,
00292              rtx, int);
00293 static void frv_frame_access_multi    (frv_frame_accessor_t*,
00294              frv_stack_t *, int);
00295 static void frv_frame_access_standard_regs  (enum frv_stack_op,
00296              frv_stack_t *);
00297 static struct machine_function *frv_init_machine_status   (void);
00298 static int frv_legitimate_memory_operand  (rtx, enum machine_mode, int);
00299 static rtx frv_int_to_acc     (enum insn_code, int, rtx);
00300 static enum machine_mode frv_matching_accg_mode (enum machine_mode);
00301 static rtx frv_read_argument      (tree *);
00302 static rtx frv_read_iacc_argument   (enum machine_mode, tree *);
00303 static int frv_check_constant_argument    (enum insn_code, int, rtx);
00304 static rtx frv_legitimize_target    (enum insn_code, rtx);
00305 static rtx frv_legitimize_argument    (enum insn_code, int, rtx);
00306 static rtx frv_legitimize_tls_address   (rtx, enum tls_model);
00307 static rtx frv_expand_set_builtin   (enum insn_code, tree, rtx);
00308 static rtx frv_expand_unop_builtin    (enum insn_code, tree, rtx);
00309 static rtx frv_expand_binop_builtin   (enum insn_code, tree, rtx);
00310 static rtx frv_expand_cut_builtin   (enum insn_code, tree, rtx);
00311 static rtx frv_expand_binopimm_builtin    (enum insn_code, tree, rtx);
00312 static rtx frv_expand_voidbinop_builtin   (enum insn_code, tree);
00313 static rtx frv_expand_int_void2arg    (enum insn_code, tree);
00314 static rtx frv_expand_prefetches    (enum insn_code, tree);
00315 static rtx frv_expand_voidtriop_builtin   (enum insn_code, tree);
00316 static rtx frv_expand_voidaccop_builtin   (enum insn_code, tree);
00317 static rtx frv_expand_mclracc_builtin   (tree);
00318 static rtx frv_expand_mrdacc_builtin    (enum insn_code, tree);
00319 static rtx frv_expand_mwtacc_builtin    (enum insn_code, tree);
00320 static rtx frv_expand_noargs_builtin    (enum insn_code);
00321 static void frv_split_iacc_move     (rtx, rtx);
00322 static rtx frv_emit_comparison      (enum rtx_code, rtx, rtx);
00323 static int frv_clear_registers_used   (rtx *, void *);
00324 static void frv_ifcvt_add_insn      (rtx, rtx, int);
00325 static rtx frv_ifcvt_rewrite_mem    (rtx, enum machine_mode, rtx);
00326 static rtx frv_ifcvt_load_value     (rtx, rtx);
00327 static int frv_acc_group_1      (rtx *, void *);
00328 static unsigned int frv_insn_unit   (rtx);
00329 static bool frv_issues_to_branch_unit_p   (rtx);
00330 static int frv_cond_flags       (rtx);
00331 static bool frv_regstate_conflict_p     (regstate_t, regstate_t);
00332 static int frv_registers_conflict_p_1     (rtx *, void *);
00333 static bool frv_registers_conflict_p    (rtx);
00334 static void frv_registers_update_1    (rtx, rtx, void *);
00335 static void frv_registers_update    (rtx);
00336 static void frv_start_packet      (void);
00337 static void frv_start_packet_block    (void);
00338 static void frv_finish_packet       (void (*) (void));
00339 static bool frv_pack_insn_p       (rtx);
00340 static void frv_add_insn_to_packet    (rtx);
00341 static void frv_insert_nop_in_packet    (rtx);
00342 static bool frv_for_each_packet     (void (*) (void));
00343 static bool frv_sort_insn_group_1   (enum frv_insn_group,
00344              unsigned int, unsigned int,
00345              unsigned int, unsigned int,
00346              state_t);
00347 static int frv_compare_insns      (const void *, const void *);
00348 static void frv_sort_insn_group     (enum frv_insn_group);
00349 static void frv_reorder_packet      (void);
00350 static void frv_fill_unused_units   (enum frv_insn_group);
00351 static void frv_align_label       (void);
00352 static void frv_reorg_packet      (void);
00353 static void frv_register_nop      (rtx);
00354 static void frv_reorg         (void);
00355 static void frv_pack_insns      (void);
00356 static void frv_function_prologue   (FILE *, HOST_WIDE_INT);
00357 static void frv_function_epilogue   (FILE *, HOST_WIDE_INT);
00358 static bool frv_assemble_integer    (rtx, unsigned, int);
00359 static void frv_init_builtins     (void);
00360 static rtx frv_expand_builtin     (tree, rtx, rtx, enum machine_mode, int);
00361 static void frv_init_libfuncs     (void);
00362 static bool frv_in_small_data_p     (tree);
00363 static void frv_asm_output_mi_thunk
00364   (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
00365 static void frv_setup_incoming_varargs    (CUMULATIVE_ARGS *,
00366              enum machine_mode,
00367              tree, int *, int);
00368 static rtx frv_expand_builtin_saveregs    (void);
00369 static bool frv_rtx_costs     (rtx, int, int, int*);
00370 static void frv_asm_out_constructor   (rtx, int);
00371 static void frv_asm_out_destructor    (rtx, int);
00372 static bool frv_function_symbol_referenced_p  (rtx);
00373 static bool frv_cannot_force_const_mem    (rtx);
00374 static const char *unspec_got_name    (int);
00375 static void frv_output_const_unspec   (FILE *,
00376              const struct frv_unspec *);
00377 static bool frv_function_ok_for_sibcall   (tree, tree);
00378 static rtx frv_struct_value_rtx     (tree, int);
00379 static bool frv_must_pass_in_stack (enum machine_mode mode, tree type);
00380 static int frv_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
00381           tree, bool);
00382 
00383 /* Initialize the GCC target structure.  */
00384 #undef  TARGET_ASM_FUNCTION_PROLOGUE
00385 #define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue
00386 #undef  TARGET_ASM_FUNCTION_EPILOGUE
00387 #define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue
00388 #undef  TARGET_ASM_INTEGER
00389 #define TARGET_ASM_INTEGER frv_assemble_integer
00390 #undef TARGET_INIT_BUILTINS
00391 #define TARGET_INIT_BUILTINS frv_init_builtins
00392 #undef TARGET_EXPAND_BUILTIN
00393 #define TARGET_EXPAND_BUILTIN frv_expand_builtin
00394 #undef TARGET_INIT_LIBFUNCS
00395 #define TARGET_INIT_LIBFUNCS frv_init_libfuncs
00396 #undef TARGET_IN_SMALL_DATA_P
00397 #define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
00398 #undef TARGET_RTX_COSTS
00399 #define TARGET_RTX_COSTS frv_rtx_costs
00400 #undef TARGET_ASM_CONSTRUCTOR
00401 #define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor
00402 #undef TARGET_ASM_DESTRUCTOR
00403 #define TARGET_ASM_DESTRUCTOR frv_asm_out_destructor
00404 
00405 #undef TARGET_ASM_OUTPUT_MI_THUNK
00406 #define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
00407 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
00408 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
00409 
00410 #undef  TARGET_SCHED_ISSUE_RATE
00411 #define TARGET_SCHED_ISSUE_RATE frv_issue_rate
00412 
00413 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
00414 #define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
00415 #undef TARGET_CANNOT_FORCE_CONST_MEM
00416 #define TARGET_CANNOT_FORCE_CONST_MEM frv_cannot_force_const_mem
00417 
00418 #undef TARGET_HAVE_TLS
00419 #define TARGET_HAVE_TLS HAVE_AS_TLS
00420 
00421 #undef TARGET_STRUCT_VALUE_RTX
00422 #define TARGET_STRUCT_VALUE_RTX frv_struct_value_rtx
00423 #undef TARGET_MUST_PASS_IN_STACK
00424 #define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack
00425 #undef TARGET_PASS_BY_REFERENCE
00426 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
00427 #undef TARGET_ARG_PARTIAL_BYTES
00428 #define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes
00429 
00430 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
00431 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
00432 #undef TARGET_SETUP_INCOMING_VARARGS
00433 #define TARGET_SETUP_INCOMING_VARARGS frv_setup_incoming_varargs
00434 #undef TARGET_MACHINE_DEPENDENT_REORG
00435 #define TARGET_MACHINE_DEPENDENT_REORG frv_reorg
00436 
00437 struct gcc_target targetm = TARGET_INITIALIZER;
00438 
00439 #define FRV_SYMBOL_REF_TLS_P(RTX) \
00440   (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
00441 
00442 
00443 /* Any function call that satisfies the machine-independent
00444    requirements is eligible on FR-V.  */
00445 
00446 static bool
00447 frv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
00448            tree exp ATTRIBUTE_UNUSED)
00449 {
00450   return true;
00451 }
00452 
00453 /* Return true if SYMBOL is a small data symbol and relocation RELOC
00454    can be used to access it directly in a load or store.  */
00455 
00456 static FRV_INLINE bool
00457 frv_small_data_reloc_p (rtx symbol, int reloc)
00458 {
00459   return (GET_CODE (symbol) == SYMBOL_REF
00460     && SYMBOL_REF_SMALL_P (symbol)
00461     && (!TARGET_FDPIC || flag_pic == 1)
00462     && (reloc == R_FRV_GOTOFF12 || reloc == R_FRV_GPREL12));
00463 }
00464 
00465 /* Return true if X is a valid relocation unspec.  If it is, fill in UNSPEC
00466    appropriately.  */
00467 
00468 static FRV_INLINE bool
00469 frv_const_unspec_p (rtx x, struct frv_unspec *unspec)
00470 {
00471   if (GET_CODE (x) == CONST)
00472     {
00473       unspec->offset = 0;
00474       x = XEXP (x, 0);
00475       if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
00476   {
00477     unspec->offset += INTVAL (XEXP (x, 1));
00478     x = XEXP (x, 0);
00479   }
00480       if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_GOT)
00481   {
00482     unspec->symbol = XVECEXP (x, 0, 0);
00483     unspec->reloc = INTVAL (XVECEXP (x, 0, 1));
00484 
00485     if (unspec->offset == 0)
00486       return true;
00487 
00488     if (frv_small_data_reloc_p (unspec->symbol, unspec->reloc)
00489         && unspec->offset > 0
00490         && (unsigned HOST_WIDE_INT) unspec->offset < g_switch_value)
00491       return true;
00492   }
00493     }
00494   return false;
00495 }
00496 
00497 /* Decide whether we can force certain constants to memory.  If we
00498    decide we can't, the caller should be able to cope with it in
00499    another way.
00500 
00501    We never allow constants to be forced into memory for TARGET_FDPIC.
00502    This is necessary for several reasons:
00503 
00504    1. Since LEGITIMATE_CONSTANT_P rejects constant pool addresses, the
00505       target-independent code will try to force them into the constant
00506       pool, thus leading to infinite recursion.
00507 
00508    2. We can never introduce new constant pool references during reload.
00509       Any such reference would require use of the pseudo FDPIC register.
00510 
00511    3. We can't represent a constant added to a function pointer (which is
00512       not the same as a pointer to a function+constant).
00513 
00514    4. In many cases, it's more efficient to calculate the constant in-line.  */
00515 
00516 static bool
00517 frv_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
00518 {
00519   return TARGET_FDPIC;
00520 }
00521 
00522 static int
00523 frv_default_flags_for_cpu (void)
00524 {
00525   switch (frv_cpu_type)
00526     {
00527     case FRV_CPU_GENERIC:
00528       return MASK_DEFAULT_FRV;
00529 
00530     case FRV_CPU_FR550:
00531       return MASK_DEFAULT_FR550;
00532 
00533     case FRV_CPU_FR500:
00534     case FRV_CPU_TOMCAT:
00535       return MASK_DEFAULT_FR500;
00536 
00537     case FRV_CPU_FR450:
00538       return MASK_DEFAULT_FR450;
00539 
00540     case FRV_CPU_FR405:
00541     case FRV_CPU_FR400:
00542       return MASK_DEFAULT_FR400;
00543 
00544     case FRV_CPU_FR300:
00545     case FRV_CPU_SIMPLE:
00546       return MASK_DEFAULT_SIMPLE;
00547     }
00548   abort ();
00549 }
00550 
00551 /* Sometimes certain combinations of command options do not make
00552    sense on a particular target machine.  You can define a macro
00553    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
00554    defined, is executed once just after all the command options have
00555    been parsed.
00556 
00557    Don't use this macro to turn on various extra optimizations for
00558    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
00559 
00560 void
00561 frv_override_options (void)
00562 {
00563   int regno;
00564   unsigned int i;
00565 
00566   /* Set the cpu type.  */
00567   if (frv_cpu_string)
00568     {
00569       if (strcmp (frv_cpu_string, "simple") == 0)
00570   frv_cpu_type = FRV_CPU_SIMPLE;
00571 
00572       else if (strcmp (frv_cpu_string, "tomcat") == 0)
00573   frv_cpu_type = FRV_CPU_TOMCAT;
00574 
00575       else if (strncmp (frv_cpu_string, "fr", sizeof ("fr")-1) != 0)
00576   error ("Unknown cpu: -mcpu=%s", frv_cpu_string);
00577 
00578       else
00579   {
00580     const char *p = frv_cpu_string + sizeof ("fr") - 1;
00581     if (strcmp (p, "550") == 0)
00582       frv_cpu_type = FRV_CPU_FR550;
00583 
00584     else if (strcmp (p, "500") == 0)
00585       frv_cpu_type = FRV_CPU_FR500;
00586 
00587     else if (strcmp (p, "450") == 0)
00588       frv_cpu_type = FRV_CPU_FR450;
00589 
00590     else if (strcmp (p, "405") == 0)
00591       frv_cpu_type = FRV_CPU_FR405;
00592 
00593     else if (strcmp (p, "400") == 0)
00594       frv_cpu_type = FRV_CPU_FR400;
00595 
00596     else if (strcmp (p, "300") == 0)
00597       frv_cpu_type = FRV_CPU_FR300;
00598 
00599     else if (strcmp (p, "v") == 0)
00600       frv_cpu_type = FRV_CPU_GENERIC;
00601 
00602     else
00603       error ("Unknown cpu: -mcpu=%s", frv_cpu_string);
00604   }
00605     }
00606 
00607   target_flags |= (frv_default_flags_for_cpu () & ~target_flags_explicit);
00608 
00609   /* -mlibrary-pic sets -fPIC and -G0 and also suppresses warnings from the
00610      linker about linking pic and non-pic code.  */
00611   if (TARGET_LIBPIC)
00612     {
00613       if (!flag_pic)    /* -fPIC */
00614   flag_pic = 2;
00615 
00616       if (! g_switch_set) /* -G0 */
00617   {
00618     g_switch_set = 1;
00619     g_switch_value = 0;
00620   }
00621     }
00622 
00623   /* Change the branch cost value.  */
00624   if (frv_branch_cost_string)
00625     frv_branch_cost_int = atoi (frv_branch_cost_string);
00626 
00627   /* Change the # of insns to be converted to conditional execution.  */
00628   if (frv_condexec_insns_str)
00629     frv_condexec_insns = atoi (frv_condexec_insns_str);
00630 
00631   /* Change # of temporary registers used to hold integer constants.  */
00632   if (frv_condexec_temps_str)
00633     frv_condexec_temps = atoi (frv_condexec_temps_str);
00634 
00635   /* Change scheduling look ahead.  */
00636   if (frv_sched_lookahead_str)
00637     frv_sched_lookahead = atoi (frv_sched_lookahead_str);
00638 
00639   /* A C expression whose value is a register class containing hard
00640      register REGNO.  In general there is more than one such class;
00641      choose a class which is "minimal", meaning that no smaller class
00642      also contains the register.  */
00643 
00644   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00645     {
00646       enum reg_class class;
00647 
00648       if (GPR_P (regno))
00649   {
00650     int gpr_reg = regno - GPR_FIRST;
00651 
00652     if (gpr_reg == GR8_REG)
00653       class = GR8_REGS;
00654 
00655     else if (gpr_reg == GR9_REG)
00656       class = GR9_REGS;
00657 
00658     else if (gpr_reg == GR14_REG)
00659       class = FDPIC_FPTR_REGS;
00660 
00661     else if (gpr_reg == FDPIC_REGNO)
00662       class = FDPIC_REGS;
00663 
00664     else if ((gpr_reg & 3) == 0)
00665       class = QUAD_REGS;
00666 
00667     else if ((gpr_reg & 1) == 0)
00668       class = EVEN_REGS;
00669 
00670     else
00671       class = GPR_REGS;
00672   }
00673 
00674       else if (FPR_P (regno))
00675   {
00676     int fpr_reg = regno - GPR_FIRST;
00677     if ((fpr_reg & 3) == 0)
00678       class = QUAD_FPR_REGS;
00679 
00680     else if ((fpr_reg & 1) == 0)
00681       class = FEVEN_REGS;
00682 
00683     else
00684       class = FPR_REGS;
00685   }
00686 
00687       else if (regno == LR_REGNO)
00688   class = LR_REG;
00689 
00690       else if (regno == LCR_REGNO)
00691   class = LCR_REG;
00692 
00693       else if (ICC_P (regno))
00694   class = ICC_REGS;
00695 
00696       else if (FCC_P (regno))
00697   class = FCC_REGS;
00698 
00699       else if (ICR_P (regno))
00700   class = ICR_REGS;
00701 
00702       else if (FCR_P (regno))
00703   class = FCR_REGS;
00704 
00705       else if (ACC_P (regno))
00706   {
00707     int r = regno - ACC_FIRST;
00708     if ((r & 3) == 0)
00709       class = QUAD_ACC_REGS;
00710     else if ((r & 1) == 0)
00711       class = EVEN_ACC_REGS;
00712     else
00713       class = ACC_REGS;
00714   }
00715 
00716       else if (ACCG_P (regno))
00717   class = ACCG_REGS;
00718 
00719       else
00720   class = NO_REGS;
00721 
00722       regno_reg_class[regno] = class;
00723     }
00724 
00725   /* Check for small data option */
00726   if (!g_switch_set)
00727     g_switch_value = SDATA_DEFAULT_SIZE;
00728 
00729   /* A C expression which defines the machine-dependent operand
00730      constraint letters for register classes.  If CHAR is such a
00731      letter, the value should be the register class corresponding to
00732      it.  Otherwise, the value should be `NO_REGS'.  The register
00733      letter `r', corresponding to class `GENERAL_REGS', will not be
00734      passed to this macro; you do not need to handle it.
00735 
00736      The following letters are unavailable, due to being used as
00737      constraints:
00738   '0'..'9'
00739   '<', '>'
00740   'E', 'F', 'G', 'H'
00741   'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'
00742   'Q', 'R', 'S', 'T', 'U'
00743   'V', 'X'
00744   'g', 'i', 'm', 'n', 'o', 'p', 'r', 's' */
00745 
00746   for (i = 0; i < 256; i++)
00747     reg_class_from_letter[i] = NO_REGS;
00748 
00749   reg_class_from_letter['a'] = ACC_REGS;
00750   reg_class_from_letter['b'] = EVEN_ACC_REGS;
00751   reg_class_from_letter['c'] = CC_REGS;
00752   reg_class_from_letter['d'] = GPR_REGS;
00753   reg_class_from_letter['e'] = EVEN_REGS;
00754   reg_class_from_letter['f'] = FPR_REGS;
00755   reg_class_from_letter['h'] = FEVEN_REGS;
00756   reg_class_from_letter['l'] = LR_REG;
00757   reg_class_from_letter['q'] = QUAD_REGS;
00758   reg_class_from_letter['t'] = ICC_REGS;
00759   reg_class_from_letter['u'] = FCC_REGS;
00760   reg_class_from_letter['v'] = ICR_REGS;
00761   reg_class_from_letter['w'] = FCR_REGS;
00762   reg_class_from_letter['x'] = QUAD_FPR_REGS;
00763   reg_class_from_letter['y'] = LCR_REG;
00764   reg_class_from_letter['z'] = SPR_REGS;
00765   reg_class_from_letter['A'] = QUAD_ACC_REGS;
00766   reg_class_from_letter['B'] = ACCG_REGS;
00767   reg_class_from_letter['C'] = CR_REGS;
00768   reg_class_from_letter['W'] = FDPIC_CALL_REGS; /* gp14+15 */
00769   reg_class_from_letter['Z'] = FDPIC_REGS; /* gp15 */
00770 
00771   /* There is no single unaligned SI op for PIC code.  Sometimes we
00772      need to use ".4byte" and sometimes we need to use ".picptr".
00773      See frv_assemble_integer for details.  */
00774   if (flag_pic || TARGET_FDPIC)
00775     targetm.asm_out.unaligned_op.si = 0;
00776 
00777   if ((target_flags_explicit & MASK_LINKED_FP) == 0)
00778     target_flags |= MASK_LINKED_FP;
00779 
00780   for (i = 0; i < ARRAY_SIZE (frv_unit_names); i++)
00781     frv_unit_codes[i] = get_cpu_unit_code (frv_unit_names[i]);
00782 
00783   for (i = 0; i < ARRAY_SIZE (frv_type_to_unit); i++)
00784     frv_type_to_unit[i] = ARRAY_SIZE (frv_unit_codes);
00785 
00786   init_machine_status = frv_init_machine_status;
00787 }
00788 
00789 
00790 /* Some machines may desire to change what optimizations are performed for
00791    various optimization levels.  This macro, if defined, is executed once just
00792    after the optimization level is determined and before the remainder of the
00793    command options have been parsed.  Values set in this macro are used as the
00794    default values for the other command line options.
00795 
00796    LEVEL is the optimization level specified; 2 if `-O2' is specified, 1 if
00797    `-O' is specified, and 0 if neither is specified.
00798 
00799    SIZE is nonzero if `-Os' is specified, 0 otherwise.
00800 
00801    You should not use this macro to change options that are not
00802    machine-specific.  These should uniformly selected by the same optimization
00803    level on all supported machines.  Use this macro to enable machbine-specific
00804    optimizations.
00805 
00806    *Do not examine `write_symbols' in this macro!* The debugging options are
00807    *not supposed to alter the generated code.  */
00808 
00809 /* On the FRV, possibly disable VLIW packing which is done by the 2nd
00810    scheduling pass at the current time.  */
00811 void
00812 frv_optimization_options (int level, int size ATTRIBUTE_UNUSED)
00813 {
00814   if (level >= 2)
00815     {
00816 #ifdef DISABLE_SCHED2
00817       flag_schedule_insns_after_reload = 0;
00818 #endif
00819 #ifdef ENABLE_RCSP
00820       flag_rcsp = 1;
00821 #endif
00822     }
00823 }
00824 
00825 
00826 /* Return true if NAME (a STRING_CST node) begins with PREFIX.  */
00827 
00828 static int
00829 frv_string_begins_with (tree name, const char *prefix)
00830 {
00831   int prefix_len = strlen (prefix);
00832 
00833   /* Remember: NAME's length includes the null terminator.  */
00834   return (TREE_STRING_LENGTH (name) > prefix_len
00835     && strncmp (TREE_STRING_POINTER (name), prefix, prefix_len) == 0);
00836 }
00837 
00838 /* Zero or more C statements that may conditionally modify two variables
00839    `fixed_regs' and `call_used_regs' (both of type `char []') after they have
00840    been initialized from the two preceding macros.
00841 
00842    This is necessary in case the fixed or call-clobbered registers depend on
00843    target flags.
00844 
00845    You need not define this macro if it has no work to do.
00846 
00847    If the usage of an entire class of registers depends on the target flags,
00848    you may indicate this to GCC by using this macro to modify `fixed_regs' and
00849    `call_used_regs' to 1 for each of the registers in the classes which should
00850    not be used by GCC.  Also define the macro `REG_CLASS_FROM_LETTER' to return
00851    `NO_REGS' if it is called with a letter for a class that shouldn't be used.
00852 
00853    (However, if this class is not included in `GENERAL_REGS' and all of the
00854    insn patterns whose constraints permit this class are controlled by target
00855    switches, then GCC will automatically avoid using these registers when the
00856    target switches are opposed to them.)  */
00857 
00858 void
00859 frv_conditional_register_usage (void)
00860 {
00861   int i;
00862 
00863   for (i = GPR_FIRST + NUM_GPRS; i <= GPR_LAST; i++)
00864     fixed_regs[i] = call_used_regs[i] = 1;
00865 
00866   for (i = FPR_FIRST + NUM_FPRS; i <= FPR_LAST; i++)
00867     fixed_regs[i] = call_used_regs[i] = 1;
00868 
00869   /* Reserve the registers used for conditional execution.  At present, we need
00870      1 ICC and 1 ICR register.  */
00871   fixed_regs[ICC_TEMP] = call_used_regs[ICC_TEMP] = 1;
00872   fixed_regs[ICR_TEMP] = call_used_regs[ICR_TEMP] = 1;
00873 
00874   if (TARGET_FIXED_CC)
00875     {
00876       fixed_regs[ICC_FIRST] = call_used_regs[ICC_FIRST] = 1;
00877       fixed_regs[FCC_FIRST] = call_used_regs[FCC_FIRST] = 1;
00878       fixed_regs[ICR_FIRST] = call_used_regs[ICR_FIRST] = 1;
00879       fixed_regs[FCR_FIRST] = call_used_regs[FCR_FIRST] = 1;
00880     }
00881 
00882   if (TARGET_FDPIC)
00883     fixed_regs[GPR_FIRST + 16] = fixed_regs[GPR_FIRST + 17] =
00884       call_used_regs[GPR_FIRST + 16] = call_used_regs[GPR_FIRST + 17] = 0;
00885 
00886 #if 0
00887   /* If -fpic, SDA_BASE_REG is the PIC register.  */
00888   if (g_switch_value == 0 && !flag_pic)
00889     fixed_regs[SDA_BASE_REG] = call_used_regs[SDA_BASE_REG] = 0;
00890 
00891   if (!flag_pic)
00892     fixed_regs[PIC_REGNO] = call_used_regs[PIC_REGNO] = 0;
00893 #endif
00894 }
00895 
00896 
00897 /*
00898  * Compute the stack frame layout
00899  *
00900  * Register setup:
00901  * +---------------+-----------------------+-----------------------+
00902  * |Register       |type                   |caller-save/callee-save|
00903  * +---------------+-----------------------+-----------------------+
00904  * |GR0            |Zero register          |        -              |
00905  * |GR1            |Stack pointer(SP)      |        -              |
00906  * |GR2            |Frame pointer(FP)      |        -              |
00907  * |GR3            |Hidden parameter       |        caller save    |
00908  * |GR4-GR7        |        -              |        caller save    |
00909  * |GR8-GR13       |Argument register      |        caller save    |
00910  * |GR14-GR15      |        -              |        caller save    |
00911  * |GR16-GR31      |        -              |        callee save    |
00912  * |GR32-GR47      |        -              |        caller save    |
00913  * |GR48-GR63      |        -              |        callee save    |
00914  * |FR0-FR15       |        -              |        caller save    |
00915  * |FR16-FR31      |        -              |        callee save    |
00916  * |FR32-FR47      |        -              |        caller save    |
00917  * |FR48-FR63      |        -              |        callee save    |
00918  * +---------------+-----------------------+-----------------------+
00919  *
00920  * Stack frame setup:
00921  * Low
00922  *     SP-> |-----------------------------------|
00923  *      |         Argument area   |
00924  *      |-----------------------------------|
00925  *      |  Register save area   |
00926  *      |-----------------------------------|
00927  *      | Local variable save area  |
00928  *     FP-> |-----------------------------------|
00929  *      |     Old FP      |
00930  *      |-----------------------------------|
00931  *      |    Hidden parameter save area     |
00932  *      |-----------------------------------|
00933  *      | Return address(LR) storage area   |
00934  *      |-----------------------------------|
00935  *      |     Padding for alignment         |
00936  *      |-----------------------------------|
00937  *      |     Register argument area  |
00938  * OLD SP-> |-----------------------------------|
00939  *          |       Parameter area    |
00940  *          |-----------------------------------|
00941  * High
00942  *
00943  * Argument area/Parameter area:
00944  *
00945  * When a function is called, this area is used for argument transfer.  When
00946  * the argument is set up by the caller function, this area is referred to as
00947  * the argument area.  When the argument is referenced by the callee function,
00948  * this area is referred to as the parameter area.  The area is allocated when
00949  * all arguments cannot be placed on the argument register at the time of
00950  * argument transfer.
00951  *
00952  * Register save area:
00953  *
00954  * This is a register save area that must be guaranteed for the caller
00955  * function.  This area is not secured when the register save operation is not
00956  * needed.
00957  *
00958  * Local variable save area:
00959  *
00960  * This is the area for local variables and temporary variables.
00961  *
00962  * Old FP:
00963  *
00964  * This area stores the FP value of the caller function.
00965  *
00966  * Hidden parameter save area:
00967  *
00968  * This area stores the start address of the return value storage
00969  * area for a struct/union return function.
00970  * When a struct/union is used as the return value, the caller
00971  * function stores the return value storage area start address in
00972  * register GR3 and passes it to the caller function.
00973  * The callee function interprets the address stored in the GR3
00974  * as the return value storage area start address.
00975  * When register GR3 needs to be saved into memory, the callee
00976  * function saves it in the hidden parameter save area.  This
00977  * area is not secured when the save operation is not needed.
00978  *
00979  * Return address(LR) storage area:
00980  *
00981  * This area saves the LR.  The LR stores the address of a return to the caller
00982  * function for the purpose of function calling.
00983  *
00984  * Argument register area:
00985  *
00986  * This area saves the argument register.  This area is not secured when the
00987  * save operation is not needed.
00988  *
00989  * Argument:
00990  *
00991  * Arguments, the count of which equals the count of argument registers (6
00992  * words), are positioned in registers GR8 to GR13 and delivered to the callee
00993  * function.  When a struct/union return function is called, the return value
00994  * area address is stored in register GR3.  Arguments not placed in the
00995  * argument registers will be stored in the stack argument area for transfer
00996  * purposes.  When an 8-byte type argument is to be delivered using registers,
00997  * it is divided into two and placed in two registers for transfer.  When
00998  * argument registers must be saved to memory, the callee function secures an
00999  * argument register save area in the stack.  In this case, a continuous
01000  * argument register save area must be established in the parameter area.  The
01001  * argument register save area must be allocated as needed to cover the size of
01002  * the argument register to be saved.  If the function has a variable count of
01003  * arguments, it saves all argument registers in the argument register save
01004  * area.
01005  *
01006  * Argument Extension Format:
01007  *
01008  * When an argument is to be stored in the stack, its type is converted to an
01009  * extended type in accordance with the individual argument type.  The argument
01010  * is freed by the caller function after the return from the callee function is
01011  * made.
01012  *
01013  * +-----------------------+---------------+------------------------+
01014  * |    Argument Type      |Extended Type  |Stack Storage Size(byte)|
01015  * +-----------------------+---------------+------------------------+
01016  * |char                   |int            |        4       |
01017  * |signed char            |int            |        4       |
01018  * |unsigned char          |int            |        4       |
01019  * |[signed] short int     |int            |        4       |
01020  * |unsigned short int     |int            |        4       |
01021  * |[signed] int           |No extension   |        4       |
01022  * |unsigned int           |No extension   |        4       |
01023  * |[signed] long int      |No extension   |        4       |
01024  * |unsigned long int      |No extension   |        4       |
01025  * |[signed] long long int |No extension   |        8       |
01026  * |unsigned long long int |No extension   |        8       |
01027  * |float                  |double         |        8       |
01028  * |double                 |No extension   |        8       |
01029  * |long double            |No extension   |        8       |
01030  * |pointer                |No extension   |        4       |
01031  * |struct/union           |-              |        4 (*1)      |
01032  * +-----------------------+---------------+------------------------+
01033  *
01034  * When a struct/union is to be delivered as an argument, the caller copies it
01035  * to the local variable area and delivers the address of that area.
01036  *
01037  * Return Value:
01038  *
01039  * +-------------------------------+----------------------+
01040  * |Return Value Type              |Return Value Interface|
01041  * +-------------------------------+----------------------+
01042  * |void                           |None                  |
01043  * |[signed|unsigned] char         |GR8                   |
01044  * |[signed|unsigned] short int    |GR8                   |
01045  * |[signed|unsigned] int          |GR8                   |
01046  * |[signed|unsigned] long int     |GR8                   |
01047  * |pointer                        |GR8                   |
01048  * |[signed|unsigned] long long int|GR8 & GR9             |
01049  * |float                          |GR8                   |
01050  * |double                         |GR8 & GR9             |
01051  * |long double                    |GR8 & GR9             |
01052  * |struct/union                   |(*1)                  |
01053  * +-------------------------------+----------------------+
01054  *
01055  * When a struct/union is used as the return value, the caller function stores
01056  * the start address of the return value storage area into GR3 and then passes
01057  * it to the callee function.  The callee function interprets GR3 as the start
01058  * address of the return value storage area.  When this address needs to be
01059  * saved in memory, the callee function secures the hidden parameter save area
01060  * and saves the address in that area.
01061  */
01062 
01063 frv_stack_t *
01064 frv_stack_info (void)
01065 {
01066   static frv_stack_t info, zero_info;
01067   frv_stack_t *info_ptr = &info;
01068   tree fndecl   = current_function_decl;
01069   int varargs_p   = 0;
01070   tree cur_arg;
01071   tree next_arg;
01072   int range;
01073   int alignment;
01074   int offset;
01075 
01076   /* If we've already calculated the values and reload is complete,
01077      just return now.  */
01078   if (frv_stack_cache)
01079     return frv_stack_cache;
01080 
01081   /* Zero all fields.  */
01082   info = zero_info;
01083 
01084   /* Set up the register range information.  */
01085   info_ptr->regs[STACK_REGS_GPR].name         = "gpr";
01086   info_ptr->regs[STACK_REGS_GPR].first        = LAST_ARG_REGNUM + 1;
01087   info_ptr->regs[STACK_REGS_GPR].last         = GPR_LAST;
01088   info_ptr->regs[STACK_REGS_GPR].dword_p      = TRUE;
01089 
01090   info_ptr->regs[STACK_REGS_FPR].name         = "fpr";
01091   info_ptr->regs[STACK_REGS_FPR].first        = FPR_FIRST;
01092   info_ptr->regs[STACK_REGS_FPR].last         = FPR_LAST;
01093   info_ptr->regs[STACK_REGS_FPR].dword_p      = TRUE;
01094 
01095   info_ptr->regs[STACK_REGS_LR].name          = "lr";
01096   info_ptr->regs[STACK_REGS_LR].first         = LR_REGNO;
01097   info_ptr->regs[STACK_REGS_LR].last          = LR_REGNO;
01098   info_ptr->regs[STACK_REGS_LR].special_p     = 1;
01099 
01100   info_ptr->regs[STACK_REGS_CC].name          = "cc";
01101   info_ptr->regs[STACK_REGS_CC].first         = CC_FIRST;
01102   info_ptr->regs[STACK_REGS_CC].last          = CC_LAST;
01103   info_ptr->regs[STACK_REGS_CC].field_p       = TRUE;
01104 
01105   info_ptr->regs[STACK_REGS_LCR].name         = "lcr";
01106   info_ptr->regs[STACK_REGS_LCR].first        = LCR_REGNO;
01107   info_ptr->regs[STACK_REGS_LCR].last         = LCR_REGNO;
01108 
01109   info_ptr->regs[STACK_REGS_STDARG].name      = "stdarg";
01110   info_ptr->regs[STACK_REGS_STDARG].first     = FIRST_ARG_REGNUM;
01111   info_ptr->regs[STACK_REGS_STDARG].last      = LAST_ARG_REGNUM;
01112   info_ptr->regs[STACK_REGS_STDARG].dword_p   = 1;
01113   info_ptr->regs[STACK_REGS_STDARG].special_p = 1;
01114 
01115   info_ptr->regs[STACK_REGS_STRUCT].name      = "struct";
01116   info_ptr->regs[STACK_REGS_STRUCT].first     = FRV_STRUCT_VALUE_REGNUM;
01117   info_ptr->regs[STACK_REGS_STRUCT].last      = FRV_STRUCT_VALUE_REGNUM;
01118   info_ptr->regs[STACK_REGS_STRUCT].special_p = 1;
01119 
01120   info_ptr->regs[STACK_REGS_FP].name          = "fp";
01121   info_ptr->regs[STACK_REGS_FP].first         = FRAME_POINTER_REGNUM;
01122   info_ptr->regs[STACK_REGS_FP].last          = FRAME_POINTER_REGNUM;
01123   info_ptr->regs[STACK_REGS_FP].special_p     = 1;
01124 
01125   /* Determine if this is a stdarg function.  If so, allocate space to store
01126      the 6 arguments.  */
01127   if (cfun->stdarg)
01128     varargs_p = 1;
01129 
01130   else
01131     {
01132       /* Find the last argument, and see if it is __builtin_va_alist.  */
01133       for (cur_arg = DECL_ARGUMENTS (fndecl); cur_arg != (tree)0; cur_arg = next_arg)
01134   {
01135     next_arg = TREE_CHAIN (cur_arg);
01136     if (next_arg == (tree)0)
01137       {
01138         if (DECL_NAME (cur_arg)
01139       && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), "__builtin_va_alist"))
01140     varargs_p = 1;
01141 
01142         break;
01143       }
01144   }
01145     }
01146 
01147   /* Iterate over all of the register ranges.  */
01148   for (range = 0; range < STACK_REGS_MAX; range++)
01149     {
01150       frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
01151       int first = reg_ptr->first;
01152       int last = reg_ptr->last;
01153       int size_1word = 0;
01154       int size_2words = 0;
01155       int regno;
01156 
01157       /* Calculate which registers need to be saved & save area size.  */
01158       switch (range)
01159   {
01160   default:
01161     for (regno = first; regno <= last; regno++)
01162       {
01163         if ((regs_ever_live[regno] && !call_used_regs[regno])
01164       || (current_function_calls_eh_return
01165           && (regno >= FIRST_EH_REGNUM && regno <= LAST_EH_REGNUM))
01166       || (!TARGET_FDPIC && flag_pic
01167           && cfun->uses_pic_offset_table && regno == PIC_REGNO))
01168     {
01169       info_ptr->save_p[regno] = REG_SAVE_1WORD;
01170       size_1word += UNITS_PER_WORD;
01171     }
01172       }
01173     break;
01174 
01175     /* Calculate whether we need to create a frame after everything else
01176              has been processed.  */
01177   case STACK_REGS_FP:
01178     break;
01179 
01180   case STACK_REGS_LR:
01181     if (regs_ever_live[LR_REGNO]
01182               || profile_flag
01183         /* This is set for __builtin_return_address, etc.  */
01184         || cfun->machine->frame_needed
01185               || (TARGET_LINKED_FP && frame_pointer_needed)
01186               || (!TARGET_FDPIC && flag_pic
01187       && cfun->uses_pic_offset_table))
01188       {
01189         info_ptr->save_p[LR_REGNO] = REG_SAVE_1WORD;
01190         size_1word += UNITS_PER_WORD;
01191       }
01192     break;
01193 
01194   case STACK_REGS_STDARG:
01195     if (varargs_p)
01196       {
01197         /* If this is a stdarg function with a non varardic
01198      argument split between registers and the stack,
01199      adjust the saved registers downward.  */
01200         last -= (ADDR_ALIGN (cfun->pretend_args_size, UNITS_PER_WORD)
01201            / UNITS_PER_WORD);
01202 
01203         for (regno = first; regno <= last; regno++)
01204     {
01205       info_ptr->save_p[regno] = REG_SAVE_1WORD;
01206       size_1word += UNITS_PER_WORD;
01207     }
01208 
01209         info_ptr->stdarg_size = size_1word;
01210       }
01211     break;
01212 
01213   case STACK_REGS_STRUCT:
01214     if (cfun->returns_struct)
01215       {
01216         info_ptr->save_p[FRV_STRUCT_VALUE_REGNUM] = REG_SAVE_1WORD;
01217         size_1word += UNITS_PER_WORD;
01218       }
01219     break;
01220   }
01221 
01222 
01223       if (size_1word)
01224   {
01225     /* If this is a field, it only takes one word.  */
01226     if (reg_ptr->field_p)
01227       size_1word = UNITS_PER_WORD;
01228 
01229     /* Determine which register pairs can be saved together.  */
01230     else if (reg_ptr->dword_p && TARGET_DWORD)
01231       {
01232         for (regno = first; regno < last; regno += 2)
01233     {
01234       if (info_ptr->save_p[regno] && info_ptr->save_p[regno+1])
01235         {
01236           size_2words += 2 * UNITS_PER_WORD;
01237           size_1word -= 2 * UNITS_PER_WORD;
01238           info_ptr->save_p[regno] = REG_SAVE_2WORDS;
01239           info_ptr->save_p[regno+1] = REG_SAVE_NO_SAVE;
01240         }
01241     }
01242       }
01243 
01244     reg_ptr->size_1word = size_1word;
01245     reg_ptr->size_2words = size_2words;
01246 
01247     if (! reg_ptr->special_p)
01248       {
01249         info_ptr->regs_size_1word += size_1word;
01250         info_ptr->regs_size_2words += size_2words;
01251       }
01252   }
01253     }
01254 
01255   /* Set up the sizes of each each field in the frame body, making the sizes
01256      of each be divisible by the size of a dword if dword operations might
01257      be used, or the size of a word otherwise.  */
01258   alignment = (TARGET_DWORD? 2 * UNITS_PER_WORD : UNITS_PER_WORD);
01259 
01260   info_ptr->parameter_size = ADDR_ALIGN (cfun->outgoing_args_size, alignment);
01261   info_ptr->regs_size = ADDR_ALIGN (info_ptr->regs_size_2words
01262             + info_ptr->regs_size_1word,
01263             alignment);
01264   info_ptr->vars_size = ADDR_ALIGN (get_frame_size (), alignment);
01265 
01266   info_ptr->pretend_size = cfun->pretend_args_size;
01267 
01268   /* Work out the size of the frame, excluding the header.  Both the frame
01269      body and register parameter area will be dword-aligned.  */
01270   info_ptr->total_size
01271     = (ADDR_ALIGN (info_ptr->parameter_size
01272        + info_ptr->regs_size
01273        + info_ptr->vars_size,
01274        2 * UNITS_PER_WORD)
01275        + ADDR_ALIGN (info_ptr->pretend_size
01276          + info_ptr->stdarg_size,
01277          2 * UNITS_PER_WORD));
01278 
01279   /* See if we need to create a frame at all, if so add header area.  */
01280   if (info_ptr->total_size  > 0
01281       || frame_pointer_needed
01282       || info_ptr->regs[STACK_REGS_LR].size_1word > 0
01283       || info_ptr->regs[STACK_REGS_STRUCT].size_1word > 0)
01284     {
01285       offset = info_ptr->parameter_size;
01286       info_ptr->header_size = 4 * UNITS_PER_WORD;
01287       info_ptr->total_size += 4 * UNITS_PER_WORD;
01288 
01289       /* Calculate the offsets to save normal register pairs.  */
01290       for (range = 0; range < STACK_REGS_MAX; range++)
01291   {
01292     frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
01293     if (! reg_ptr->special_p)
01294       {
01295         int first = reg_ptr->first;
01296         int last = reg_ptr->last;
01297         int regno;
01298 
01299         for (regno = first; regno <= last; regno++)
01300     if (info_ptr->save_p[regno] == REG_SAVE_2WORDS
01301         && regno != FRAME_POINTER_REGNUM
01302         && (regno < FIRST_ARG_REGNUM
01303       || regno > LAST_ARG_REGNUM))
01304       {
01305         info_ptr->reg_offset[regno] = offset;
01306         offset += 2 * UNITS_PER_WORD;
01307       }
01308       }
01309   }
01310 
01311       /* Calculate the offsets to save normal single registers.  */
01312       for (range = 0; range < STACK_REGS_MAX; range++)
01313   {
01314     frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
01315     if (! reg_ptr->special_p)
01316       {
01317         int first = reg_ptr->first;
01318         int last = reg_ptr->last;
01319         int regno;
01320 
01321         for (regno = first; regno <= last; regno++)
01322     if (info_ptr->save_p[regno] == REG_SAVE_1WORD
01323         && regno != FRAME_POINTER_REGNUM
01324         && (regno < FIRST_ARG_REGNUM
01325       || regno > LAST_ARG_REGNUM))
01326       {
01327         info_ptr->reg_offset[regno] = offset;
01328         offset += UNITS_PER_WORD;
01329       }
01330       }
01331   }
01332 
01333       /* Calculate the offset to save the local variables at.  */
01334       offset = ADDR_ALIGN (offset, alignment);
01335       if (info_ptr->vars_size)
01336   {
01337     info_ptr->vars_offset = offset;
01338     offset += info_ptr->vars_size;
01339   }
01340 
01341       /* Align header to a dword-boundary.  */
01342       offset = ADDR_ALIGN (offset, 2 * UNITS_PER_WORD);
01343 
01344       /* Calculate the offsets in the fixed frame.  */
01345       info_ptr->save_p[FRAME_POINTER_REGNUM] = REG_SAVE_1WORD;
01346       info_ptr->reg_offset[FRAME_POINTER_REGNUM] = offset;
01347       info_ptr->regs[STACK_REGS_FP].size_1word = UNITS_PER_WORD;
01348 
01349       info_ptr->save_p[LR_REGNO] = REG_SAVE_1WORD;
01350       info_ptr->reg_offset[LR_REGNO] = offset + 2*UNITS_PER_WORD;
01351       info_ptr->regs[STACK_REGS_LR].size_1word = UNITS_PER_WORD;
01352 
01353       if (cfun->returns_struct)
01354   {
01355     info_ptr->save_p[FRV_STRUCT_VALUE_REGNUM] = REG_SAVE_1WORD;
01356     info_ptr->reg_offset[FRV_STRUCT_VALUE_REGNUM] = offset + UNITS_PER_WORD;
01357     info_ptr->regs[STACK_REGS_STRUCT].size_1word = UNITS_PER_WORD;
01358   }
01359 
01360       /* Calculate the offsets to store the arguments passed in registers
01361          for stdarg functions.  The register pairs are first and the single
01362          register if any is last.  The register save area starts on a
01363          dword-boundary.  */
01364       if (info_ptr->stdarg_size)
01365   {
01366     int first = info_ptr->regs[STACK_REGS_STDARG].first;
01367     int last  = info_ptr->regs[STACK_REGS_STDARG].last;
01368     int regno;
01369 
01370     /* Skip the header.  */
01371     offset += 4 * UNITS_PER_WORD;
01372     for (regno = first; regno <= last; regno++)
01373       {
01374         if (info_ptr->save_p[regno] == REG_SAVE_2WORDS)
01375     {
01376       info_ptr->reg_offset[regno] = offset;
01377       offset += 2 * UNITS_PER_WORD;
01378     }
01379         else if (info_ptr->save_p[regno] == REG_SAVE_1WORD)
01380     {
01381       info_ptr->reg_offset[regno] = offset;
01382       offset += UNITS_PER_WORD;
01383     }
01384       }
01385   }
01386     }
01387 
01388   if (reload_completed)
01389     frv_stack_cache = info_ptr;
01390 
01391   return info_ptr;
01392 }
01393 
01394 
01395 /* Print the information about the frv stack offsets, etc. when debugging.  */
01396 
01397 void
01398 frv_debug_stack (frv_stack_t *info)
01399 {
01400   int range;
01401 
01402   if (!info)
01403     info = frv_stack_info ();
01404 
01405   fprintf (stderr, "\nStack information for function %s:\n",
01406      ((current_function_decl && DECL_NAME (current_function_decl))
01407       ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
01408       : "<unknown>"));
01409 
01410   fprintf (stderr, "\ttotal_size\t= %6d\n", info->total_size);
01411   fprintf (stderr, "\tvars_size\t= %6d\n", info->vars_size);
01412   fprintf (stderr, "\tparam_size\t= %6d\n", info->parameter_size);
01413   fprintf (stderr, "\tregs_size\t= %6d, 1w = %3d, 2w = %3d\n",
01414      info->regs_size, info->regs_size_1word, info->regs_size_2words);
01415 
01416   fprintf (stderr, "\theader_size\t= %6d\n", info->header_size);
01417   fprintf (stderr, "\tpretend_size\t= %6d\n", info->pretend_size);
01418   fprintf (stderr, "\tvars_offset\t= %6d\n", info->vars_offset);
01419   fprintf (stderr, "\tregs_offset\t= %6d\n", info->regs_offset);
01420 
01421   for (range = 0; range < STACK_REGS_MAX; range++)
01422     {
01423       frv_stack_regs_t *regs = &(info->regs[range]);
01424       if ((regs->size_1word + regs->size_2words) > 0)
01425   {
01426     int first = regs->first;
01427     int last  = regs->last;
01428     int regno;
01429 
01430     fprintf (stderr, "\t%s\tsize\t= %6d, 1w = %3d, 2w = %3d, save =",
01431        regs->name, regs->size_1word + regs->size_2words,
01432        regs->size_1word, regs->size_2words);
01433 
01434     for (regno = first; regno <= last; regno++)
01435       {
01436         if (info->save_p[regno] == REG_SAVE_1WORD)
01437     fprintf (stderr, " %s (%d)", reg_names[regno],
01438        info->reg_offset[regno]);
01439 
01440         else if (info->save_p[regno] == REG_SAVE_2WORDS)
01441     fprintf (stderr, " %s-%s (%d)", reg_names[regno],
01442        reg_names[regno+1], info->reg_offset[regno]);
01443       }
01444 
01445     fputc ('\n', stderr);
01446   }
01447     }
01448 
01449   fflush (stderr);
01450 }
01451 
01452 
01453 
01454 
01455 /* Used during final to control the packing of insns.  The value is
01456    1 if the current instruction should be packed with the next one,
01457    0 if it shouldn't or -1 if packing is disabled altogether.  */
01458 
01459 static int frv_insn_packing_flag;
01460 
01461 /* True if the current function contains a far jump.  */
01462 
01463 static int
01464 frv_function_contains_far_jump (void)
01465 {
01466   rtx insn = get_insns ();
01467   while (insn != NULL
01468    && !(GET_CODE (insn) == JUMP_INSN
01469         /* Ignore tablejump patterns.  */
01470         && GET_CODE (PATTERN (insn)) != ADDR_VEC
01471         && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
01472         && get_attr_far_jump (insn) == FAR_JUMP_YES))
01473     insn = NEXT_INSN (insn);
01474   return (insn != NULL);
01475 }
01476 
01477 /* For the FRV, this function makes sure that a function with far jumps
01478    will return correctly.  It also does the VLIW packing.  */
01479 
01480 static void
01481 frv_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
01482 {
01483   /* If no frame was created, check whether the function uses a call
01484      instruction to implement a far jump.  If so, save the link in gr3 and
01485      replace all returns to LR with returns to GR3.  GR3 is used because it
01486      is call-clobbered, because is not available to the register allocator,
01487      and because all functions that take a hidden argument pointer will have
01488      a stack frame.  */
01489   if (frv_stack_info ()->total_size == 0 && frv_function_contains_far_jump ())
01490     {
01491       rtx insn;
01492 
01493       /* Just to check that the above comment is true.  */
01494       if (regs_ever_live[GPR_FIRST + 3])
01495   abort ();
01496 
01497       /* Generate the instruction that saves the link register.  */
01498       fprintf (file, "\tmovsg lr,gr3\n");
01499 
01500       /* Replace the LR with GR3 in *return_internal patterns.  The insn
01501    will now return using jmpl @(gr3,0) rather than bralr.  We cannot
01502    simply emit a different assembly directive because bralr and jmpl
01503    execute in different units.  */
01504       for (insn = get_insns(); insn != NULL; insn = NEXT_INSN (insn))
01505   if (GET_CODE (insn) == JUMP_INSN)
01506     {
01507       rtx pattern = PATTERN (insn);
01508       if (GET_CODE (pattern) == PARALLEL
01509     && XVECLEN (pattern, 0) >= 2
01510     && GET_CODE (XVECEXP (pattern, 0, 0)) == RETURN
01511     && GET_CODE (XVECEXP (pattern, 0, 1)) == USE)
01512         {
01513     rtx address = XEXP (XVECEXP (pattern, 0, 1), 0);
01514     if (GET_CODE (address) == REG && REGNO (address) == LR_REGNO)
01515       REGNO (address) = GPR_FIRST + 3;
01516         }
01517     }
01518     }
01519 
01520   frv_pack_insns ();
01521 
01522   /* Allow the garbage collector to free the nops created by frv_reorg.  */
01523   memset (frv_nops, 0, sizeof (frv_nops));
01524 }
01525 
01526 
01527 /* Return the next available temporary register in a given class.  */
01528 
01529 static rtx
01530 frv_alloc_temp_reg (
01531      frv_tmp_reg_t *info, /* which registers are available */
01532      enum reg_class class,  /* register class desired */
01533      enum machine_mode mode,  /* mode to allocate register with */
01534      int mark_as_used,    /* register not available after allocation */
01535      int no_abort)    /* return NULL instead of aborting */
01536 {
01537   int regno = info->next_reg[ (int)class ];
01538   int orig_regno = regno;
01539   HARD_REG_SET *reg_in_class = &reg_class_contents[ (int)class ];
01540   int i, nr;
01541 
01542   for (;;)
01543     {
01544       if (TEST_HARD_REG_BIT (*reg_in_class, regno)
01545     && TEST_HARD_REG_BIT (info->regs, regno))
01546     break;
01547 
01548       if (++regno >= FIRST_PSEUDO_REGISTER)
01549   regno = 0;
01550       if (regno == orig_regno)
01551   {
01552     if (no_abort)
01553       return NULL_RTX;
01554     else
01555       abort ();
01556   }
01557     }
01558 
01559   nr = HARD_REGNO_NREGS (regno, mode);
01560   info->next_reg[ (int)class ] = regno + nr;
01561 
01562   if (mark_as_used)
01563     for (i = 0; i < nr; i++)
01564       CLEAR_HARD_REG_BIT (info->regs, regno+i);
01565 
01566   return gen_rtx_REG (mode, regno);
01567 }
01568 
01569 
01570 /* Return an rtx with the value OFFSET, which will either be a register or a
01571    signed 12-bit integer.  It can be used as the second operand in an "add"
01572    instruction, or as the index in a load or store.
01573 
01574    The function returns a constant rtx if OFFSET is small enough, otherwise
01575    it loads the constant into register OFFSET_REGNO and returns that.  */
01576 static rtx
01577 frv_frame_offset_rtx (int offset)
01578 {
01579   rtx offset_rtx = GEN_INT (offset);
01580   if (IN_RANGE_P (offset, -2048, 2047))
01581     return offset_rtx;
01582   else
01583     {
01584       rtx reg_rtx = gen_rtx_REG (SImode, OFFSET_REGNO);
01585       if (IN_RANGE_P (offset, -32768, 32767))
01586   emit_insn (gen_movsi (reg_rtx, offset_rtx));
01587       else
01588   {
01589     emit_insn (gen_movsi_high (reg_rtx, offset_rtx));
01590     emit_insn (gen_movsi_lo_sum (reg_rtx, offset_rtx));
01591   }
01592       return reg_rtx;
01593     }
01594 }
01595 
01596 /* Generate (mem:MODE (plus:Pmode BASE (frv_frame_offset OFFSET)))).  The
01597    prologue and epilogue uses such expressions to access the stack.  */
01598 static rtx
01599 frv_frame_mem (enum machine_mode mode, rtx base, int offset)
01600 {
01601   return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode,
01602             base,
01603             frv_frame_offset_rtx (offset)));
01604 }
01605 
01606 /* Generate a frame-related expression:
01607 
01608   (set REG (mem (plus (sp) (const_int OFFSET)))).
01609 
01610    Such expressions are used in FRAME_RELATED_EXPR notes for more complex
01611    instructions.  Marking the expressions as frame-related is superfluous if
01612    the note contains just a single set.  But if the note contains a PARALLEL
01613    or SEQUENCE that has several sets, each set must be individually marked
01614    as frame-related.  */
01615 static rtx
01616 frv_dwarf_store (rtx reg, int offset)
01617 {
01618   rtx set = gen_rtx_SET (VOIDmode,
01619        gen_rtx_MEM (GET_MODE (reg),
01620               plus_constant (stack_pointer_rtx,
01621                  offset)),
01622        reg);
01623   RTX_FRAME_RELATED_P (set) = 1;
01624   return set;
01625 }
01626 
01627 /* Emit a frame-related instruction whose pattern is PATTERN.  The
01628    instruction is the last in a sequence that cumulatively performs the
01629    operation described by DWARF_PATTERN.  The instruction is marked as
01630    frame-related and has a REG_FRAME_RELATED_EXPR note containing
01631    DWARF_PATTERN.  */
01632 static void
01633 frv_frame_insn (rtx pattern, rtx dwarf_pattern)
01634 {
01635   rtx insn = emit_insn (pattern);
01636   RTX_FRAME_RELATED_P (insn) = 1;
01637   REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
01638               dwarf_pattern,
01639               REG_NOTES (insn));
01640 }
01641 
01642 /* Emit instructions that transfer REG to or from the memory location (sp +
01643    STACK_OFFSET).  The register is stored in memory if ACCESSOR->OP is
01644    FRV_STORE and loaded if it is FRV_LOAD.  Only the prologue uses this
01645    function to store registers and only the epilogue uses it to load them.
01646 
01647    The caller sets up ACCESSOR so that BASE is equal to (sp + BASE_OFFSET).
01648    The generated instruction will use BASE as its base register.  BASE may
01649    simply be the stack pointer, but if several accesses are being made to a
01650    region far away from the stack pointer, it may be more efficient to set
01651    up a temporary instead.
01652 
01653    Store instructions will be frame-related and will be annotated with the
01654    overall effect of the store.  Load instructions will be followed by a
01655    (use) to prevent later optimizations from zapping them.
01656 
01657    The function takes care of the moves to and from SPRs, using TEMP_REGNO
01658    as a temporary in such cases.  */
01659 static void
01660 frv_frame_access (frv_frame_accessor_t *accessor, rtx reg, int stack_offset)
01661 {
01662   enum machine_mode mode = GET_MODE (reg);
01663   rtx mem = frv_frame_mem (mode,
01664          accessor->base,
01665          stack_offset - accessor->base_offset);
01666 
01667   if (accessor->op == FRV_LOAD)
01668     {
01669       if (SPR_P (REGNO (reg)))
01670   {
01671     rtx temp = gen_rtx_REG (mode, TEMP_REGNO);
01672     emit_insn (gen_rtx_SET (VOIDmode, temp, mem));
01673     emit_insn (gen_rtx_SET (VOIDmode, reg, temp));
01674   }
01675       else
01676   emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
01677       emit_insn (gen_rtx_USE (VOIDmode, reg));
01678     }
01679   else
01680     {
01681       if (SPR_P (REGNO (reg)))
01682   {
01683     rtx temp = gen_rtx_REG (mode, TEMP_REGNO);
01684     emit_insn (gen_rtx_SET (VOIDmode, temp, reg));
01685     frv_frame_insn (gen_rtx_SET (Pmode, mem, temp),
01686         frv_dwarf_store (reg, stack_offset));
01687   }
01688       else if (GET_MODE (reg) == DImode)
01689   {
01690     /* For DImode saves, the dwarf2 version needs to be a SEQUENCE
01691        with a separate save for each register.  */
01692     rtx reg1 = gen_rtx_REG (SImode, REGNO (reg));
01693     rtx reg2 = gen_rtx_REG (SImode, REGNO (reg) + 1);
01694     rtx set1 = frv_dwarf_store (reg1, stack_offset);
01695     rtx set2 = frv_dwarf_store (reg2, stack_offset + 4);
01696     frv_frame_insn (gen_rtx_SET (Pmode, mem, reg),
01697         gen_rtx_PARALLEL (VOIDmode,
01698               gen_rtvec (2, set1, set2)));
01699   }
01700       else
01701   frv_frame_insn (gen_rtx_SET (Pmode, mem, reg),
01702       frv_dwarf_store (reg, stack_offset));
01703     }
01704 }
01705 
01706 /* A function that uses frv_frame_access to transfer a group of registers to
01707    or from the stack.  ACCESSOR is passed directly to frv_frame_access, INFO
01708    is the stack information generated by frv_stack_info, and REG_SET is the
01709    number of the register set to transfer.  */
01710 static void
01711 frv_frame_access_multi (frv_frame_accessor_t *accessor,
01712                         frv_stack_t *info,
01713                         int reg_set)
01714 {
01715   frv_stack_regs_t *regs_info;
01716   int regno;
01717 
01718   regs_info = &info->regs[reg_set];
01719   for (regno = regs_info->first; regno <= regs_info->last; regno++)
01720     if (info->save_p[regno])
01721       frv_frame_access (accessor,
01722       info->save_p[regno] == REG_SAVE_2WORDS
01723       ? gen_rtx_REG (DImode, regno)
01724       : gen_rtx_REG (SImode, regno),
01725       info->reg_offset[regno]);
01726 }
01727 
01728 /* Save or restore callee-saved registers that are kept outside the frame
01729    header.  The function saves the registers if OP is FRV_STORE and restores
01730    them if OP is FRV_LOAD.  INFO is the stack information generated by
01731    frv_stack_info.  */
01732 static void
01733 frv_frame_access_standard_regs (enum frv_stack_op op, frv_stack_t *info)
01734 {
01735   frv_frame_accessor_t accessor;
01736 
01737   accessor.op = op;
01738   accessor.base = stack_pointer_rtx;
01739   accessor.base_offset = 0;
01740   frv_frame_access_multi (&accessor, info, STACK_REGS_GPR);
01741   frv_frame_access_multi (&accessor, info, STACK_REGS_FPR);
01742   frv_frame_access_multi (&accessor, info, STACK_REGS_LCR);
01743 }
01744 
01745 
01746 /* Called after register allocation to add any instructions needed for the
01747    prologue.  Using a prologue insn is favored compared to putting all of the
01748    instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
01749    it allows the scheduler to intermix instructions with the saves of
01750    the caller saved registers.  In some cases, it might be necessary
01751    to emit a barrier instruction as the last insn to prevent such
01752    scheduling.
01753 
01754    Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
01755    so that the debug info generation code can handle them properly.  */
01756 void
01757 frv_expand_prologue (void)
01758 {
01759   frv_stack_t *info = frv_stack_info ();
01760   rtx sp = stack_pointer_rtx;
01761   rtx fp = frame_pointer_rtx;
01762   frv_frame_accessor_t accessor;
01763 
01764   if (TARGET_DEBUG_STACK)
01765     frv_debug_stack (info);
01766 
01767   if (info->total_size == 0)
01768     return;
01769 
01770   /* We're interested in three areas of the frame here:
01771 
01772          A: the register save area
01773    B: the old FP
01774    C: the header after B
01775 
01776      If the frame pointer isn't used, we'll have to set up A, B and C
01777      using the stack pointer.  If the frame pointer is used, we'll access
01778      them as follows:
01779 
01780          A: set up using sp
01781    B: set up using sp or a temporary (see below)
01782    C: set up using fp
01783 
01784      We set up B using the stack pointer if the frame is small enough.
01785      Otherwise, it's more efficient to copy the old stack pointer into a
01786      temporary and use that.
01787 
01788      Note that it's important to make sure the prologue and epilogue use the
01789      same registers to access A and C, since doing otherwise will confuse
01790      the aliasing code.  */
01791 
01792   /* Set up ACCESSOR for accessing region B above.  If the frame pointer
01793      isn't used, the same method will serve for C.  */
01794   accessor.op = FRV_STORE;
01795   if (frame_pointer_needed && info->total_size > 2048)
01796     {
01797       rtx insn;
01798 
01799       accessor.base = gen_rtx_REG (Pmode, OLD_SP_REGNO);
01800       accessor.base_offset = info->total_size;
01801       insn = emit_insn (gen_movsi (accessor.base, sp));
01802     }
01803   else
01804     {
01805       accessor.base = stack_pointer_rtx;
01806       accessor.base_offset = 0;
01807     }
01808 
01809   /* Allocate the stack space.  */
01810   {
01811     rtx asm_offset = frv_frame_offset_rtx (-info->total_size);
01812     rtx dwarf_offset = GEN_INT (-info->total_size);
01813 
01814     frv_frame_insn (gen_stack_adjust (sp, sp, asm_offset),
01815         gen_rtx_SET (Pmode,
01816          sp,
01817          gen_rtx_PLUS (Pmode, sp, dwarf_offset)));
01818   }
01819 
01820   /* If the frame pointer is needed, store the old one at (sp + FP_OFFSET)
01821      and point the new one to that location.  */
01822   if (frame_pointer_needed)
01823     {
01824       int fp_offset = info->reg_offset[FRAME_POINTER_REGNUM];
01825 
01826       /* ASM_SRC and DWARF_SRC both point to the frame header.  ASM_SRC is
01827    based on ACCESSOR.BASE but DWARF_SRC is always based on the stack
01828    pointer.  */
01829       rtx asm_src = plus_constant (accessor.base,
01830            fp_offset - accessor.base_offset);
01831       rtx dwarf_src = plus_constant (sp, fp_offset);
01832 
01833       /* Store the old frame pointer at (sp + FP_OFFSET).  */
01834       frv_frame_access (&accessor, fp, fp_offset);
01835 
01836       /* Set up the new frame pointer.  */
01837       frv_frame_insn (gen_rtx_SET (VOIDmode, fp, asm_src),
01838           gen_rtx_SET (VOIDmode, fp, dwarf_src));
01839 
01840       /* Access region C from the frame pointer.  */
01841       accessor.base = fp;
01842       accessor.base_offset = fp_offset;
01843     }
01844 
01845   /* Set up region C.  */
01846   frv_frame_access_multi (&accessor, info, STACK_REGS_STRUCT);
01847   frv_frame_access_multi (&accessor, info, STACK_REGS_LR);
01848   frv_frame_access_multi (&accessor, info, STACK_REGS_STDARG);
01849 
01850   /* Set up region A.  */
01851   frv_frame_access_standard_regs (FRV_STORE, info);
01852 
01853   /* If this is a varargs/stdarg function, issue a blockage to prevent the
01854      scheduler from moving loads before the stores saving the registers.  */
01855   if (info->stdarg_size > 0)
01856     emit_insn (gen_blockage ());
01857 
01858   /* Set up pic register/small data register for this function.  */
01859   if (!TARGET_FDPIC && flag_pic && cfun->uses_pic_offset_table)
01860     emit_insn (gen_pic_prologue (gen_rtx_REG (Pmode, PIC_REGNO),
01861          gen_rtx_REG (Pmode, LR_REGNO),
01862          gen_rtx_REG (SImode, OFFSET_REGNO)));
01863 }
01864 
01865 
01866 /* Under frv, all of the work is done via frv_expand_epilogue, but
01867    this function provides a convenient place to do cleanup.  */
01868 
01869 static void
01870 frv_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
01871                        HOST_WIDE_INT size ATTRIBUTE_UNUSED)
01872 {
01873   frv_stack_cache = (frv_stack_t *)0;
01874 
01875   /* Zap last used registers for conditional execution.  */
01876   memset (&frv_ifcvt.tmp_reg, 0, sizeof (frv_ifcvt.tmp_reg));
01877 
01878   /* Release the bitmap of created insns.  */
01879   BITMAP_FREE (frv_ifcvt.scratch_insns_bitmap);
01880 }
01881 
01882 
01883 /* Called after register allocation to add any instructions needed for the
01884    epilogue.  Using an epilogue insn is favored compared to putting all of the
01885    instructions in the TARGET_ASM_FUNCTION_PROLOGUE target hook, since
01886    it allows the scheduler to intermix instructions with the saves of
01887    the caller saved registers.  In some cases, it might be necessary
01888    to emit a barrier instruction as the last insn to prevent such
01889    scheduling.  */
01890 
01891 void
01892 frv_expand_epilogue (bool emit_return)
01893 {
01894   frv_stack_t *info = frv_stack_info ();
01895   rtx fp = frame_pointer_rtx;
01896   rtx sp = stack_pointer_rtx;
01897   rtx return_addr;
01898   int fp_offset;
01899 
01900   fp_offset = info->reg_offset[FRAME_POINTER_REGNUM];
01901 
01902   /* Restore the stack pointer to its original value if alloca or the like
01903      is used.  */
01904   if (! current_function_sp_is_unchanging)
01905     emit_insn (gen_addsi3 (sp, fp, frv_frame_offset_rtx (-fp_offset)));
01906 
01907   /* Restore the callee-saved registers that were used in this function.  */
01908   frv_frame_access_standard_regs (FRV_LOAD, info);
01909 
01910   /* Set RETURN_ADDR to the address we should return to.  Set it to NULL if
01911      no return instruction should be emitted.  */
01912   if (info->save_p[LR_REGNO])
01913     {
01914       int lr_offset;
01915       rtx mem;
01916 
01917       /* Use the same method to access the link register's slot as we did in
01918    the prologue.  In other words, use the frame pointer if available,
01919    otherwise use the stack pointer.
01920 
01921    LR_OFFSET is the offset of the link register's slot from the start
01922    of the frame and MEM is a memory rtx for it.  */
01923       lr_offset = info->reg_offset[LR_REGNO];
01924       if (frame_pointer_needed)
01925   mem = frv_frame_mem (Pmode, fp, lr_offset - fp_offset);
01926       else
01927   mem = frv_frame_mem (Pmode, sp, lr_offset);
01928 
01929       /* Load the old link register into a GPR.  */
01930       return_addr = gen_rtx_REG (Pmode, TEMP_REGNO);
01931       emit_insn (gen_rtx_SET (VOIDmode, return_addr, mem));
01932     }
01933   else
01934     return_addr = gen_rtx_REG (Pmode, LR_REGNO);
01935 
01936   /* Restore the old frame pointer.  Emit a USE afterwards to make sure
01937      the load is preserved.  */
01938   if (frame_pointer_needed)
01939     {
01940       emit_insn (gen_rtx_SET (VOIDmode, fp, gen_rtx_MEM (Pmode, fp)));
01941       emit_insn (gen_rtx_USE (VOIDmode, fp));
01942     }
01943 
01944   /* Deallocate the stack frame.  */
01945   if (info->total_size != 0)
01946     {
01947       rtx offset = frv_frame_offset_rtx (info->total_size);
01948       emit_insn (gen_stack_adjust (sp, sp, offset));
01949     }
01950 
01951   /* If this function uses eh_return, add the final stack adjustment now.  */
01952   if (current_function_calls_eh_return)
01953     emit_insn (gen_stack_adjust (sp, sp, EH_RETURN_STACKADJ_RTX));
01954 
01955   if (emit_return)
01956     emit_jump_insn (gen_epilogue_return (return_addr));
01957   else
01958     {
01959       rtx lr = return_addr;
01960 
01961       if (REGNO (return_addr) != LR_REGNO)
01962   {
01963     lr = gen_rtx_REG (Pmode, LR_REGNO);
01964     emit_move_insn (lr, return_addr);
01965   }
01966 
01967       emit_insn (gen_rtx_USE (VOIDmode, lr));
01968     }
01969 }
01970 
01971 
01972 /* Worker function for TARGET_ASM_OUTPUT_MI_THUNK.  */
01973 
01974 static void
01975 frv_asm_output_mi_thunk (FILE *file,
01976                          tree thunk_fndecl ATTRIBUTE_UNUSED,
01977                          HOST_WIDE_INT delta,
01978                          HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
01979                          tree function)
01980 {
01981   const char *name_func = XSTR (XEXP (DECL_RTL (function), 0), 0);
01982   const char *name_arg0 = reg_names[FIRST_ARG_REGNUM];
01983   const char *name_jmp = reg_names[JUMP_REGNO];
01984   const char *parallel = (frv_issue_rate () > 1 ? ".p" : "");
01985 
01986   /* Do the add using an addi if possible.  */
01987   if (IN_RANGE_P (delta, -2048, 2047))
01988     fprintf (file, "\taddi %s,#%d,%s\n", name_arg0, (int) delta, name_arg0);
01989   else
01990     {
01991       const char *const name_add = reg_names[TEMP_REGNO];
01992       fprintf (file, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
01993          parallel, delta, name_add);
01994       fprintf (file, "\tsetlo #lo(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
01995          delta, name_add);
01996       fprintf (file, "\tadd %s,%s,%s\n", name_add, name_arg0, name_arg0);
01997     }
01998 
01999   if (TARGET_FDPIC)
02000     {
02001       const char *name_pic = reg_names[FDPIC_REGNO];
02002       name_jmp = reg_names[FDPIC_FPTR_REGNO];
02003 
02004       if (flag_pic != 1)
02005   {
02006     fprintf (file, "\tsethi%s #gotofffuncdeschi(", parallel);
02007     assemble_name (file, name_func);
02008     fprintf (file, "),%s\n", name_jmp);
02009 
02010     fprintf (file, "\tsetlo #gotofffuncdesclo(");
02011     assemble_name (file, name_func);
02012     fprintf (file, "),%s\n", name_jmp);
02013 
02014     fprintf (file, "\tldd @(%s,%s), %s\n", name_jmp, name_pic, name_jmp);
02015   }
02016       else
02017   {
02018     fprintf (file, "\tlddo @(%s,#gotofffuncdesc12(", name_pic);
02019     assemble_name (file, name_func);
02020     fprintf (file, "\t)), %s\n", name_jmp);
02021   }
02022     }
02023   else if (!flag_pic)
02024     {
02025       fprintf (file, "\tsethi%s #hi(", parallel);
02026       assemble_name (file, name_func);
02027       fprintf (file, "),%s\n", name_jmp);
02028 
02029       fprintf (file, "\tsetlo #lo(");
02030       assemble_name (file, name_func);
02031       fprintf (file, "),%s\n", name_jmp);
02032     }
02033   else
02034     {
02035       /* Use JUMP_REGNO as a temporary PIC register.  */
02036       const char *name_lr = reg_names[LR_REGNO];
02037       const char *name_gppic = name_jmp;
02038       const char *name_tmp = reg_names[TEMP_REGNO];
02039 
02040       fprintf (file, "\tmovsg %s,%s\n", name_lr, name_tmp);
02041       fprintf (file, "\tcall 1f\n");
02042       fprintf (file, "1:\tmovsg %s,%s\n", name_lr, name_gppic);
02043       fprintf (file, "\tmovgs %s,%s\n", name_tmp, name_lr);
02044       fprintf (file, "\tsethi%s #gprelhi(1b),%s\n", parallel, name_tmp);
02045       fprintf (file, "\tsetlo #gprello(1b),%s\n", name_tmp);
02046       fprintf (file, "\tsub %s,%s,%s\n", name_gppic, name_tmp, name_gppic);
02047 
02048       fprintf (file, "\tsethi%s #gprelhi(", parallel);
02049       assemble_name (file, name_func);
02050       fprintf (file, "),%s\n", name_tmp);
02051 
02052       fprintf (file, "\tsetlo #gprello(");
02053       assemble_name (file, name_func);
02054       fprintf (file, "),%s\n", name_tmp);
02055 
02056       fprintf (file, "\tadd %s,%s,%s\n", name_gppic, name_tmp, name_jmp);
02057     }
02058 
02059   /* Jump to the function address.  */
02060   fprintf (file, "\tjmpl @(%s,%s)\n", name_jmp, reg_names[GPR_FIRST+0]);
02061 }
02062 
02063 
02064 /* A C expression which is nonzero if a function must have and use a frame
02065    pointer.  This expression is evaluated in the reload pass.  If its value is
02066    nonzero the function will have a frame pointer.
02067 
02068    The expression can in principle examine the current function and decide
02069    according to the facts, but on most machines the constant 0 or the constant
02070    1 suffices.  Use 0 when the machine allows code to be generated with no
02071    frame pointer, and doing so saves some time or space.  Use 1 when there is
02072    no possible advantage to avoiding a frame pointer.
02073 
02074    In certain cases, the compiler does not know how to produce valid code
02075    without a frame pointer.  The compiler recognizes those cases and
02076    automatically gives the function a frame pointer regardless of what
02077    `FRAME_POINTER_REQUIRED' says.  You don't need to worry about them.
02078 
02079    In a function that does not require a frame pointer, the frame pointer
02080    register can be allocated for ordinary usage, unless you mark it as a fixed
02081    register.  See `FIXED_REGISTERS' for more information.  */
02082 
02083 /* On frv, create a frame whenever we need to create stack.  */
02084 
02085 int
02086 frv_frame_pointer_required (void)
02087 {
02088   /* If we forgoing the usual linkage requirements, we only need
02089      a frame pointer if the stack pointer might change.  */
02090   if (!TARGET_LINKED_FP)
02091     return !current_function_sp_is_unchanging;
02092 
02093   if (! current_function_is_leaf)
02094     return TRUE;
02095 
02096   if (get_frame_size () != 0)
02097     return TRUE;
02098 
02099   if (cfun->stdarg)
02100     return TRUE;
02101 
02102   if (!current_function_sp_is_unchanging)
02103     return TRUE;
02104 
02105   if (!TARGET_FDPIC && flag_pic && cfun->uses_pic_offset_table)
02106     return TRUE;
02107 
02108   if (profile_flag)
02109     return TRUE;
02110 
02111   if (cfun->machine->frame_needed)
02112     return TRUE;
02113 
02114   return FALSE;
02115 }
02116 
02117 
02118 /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'.  It specifies the
02119    initial difference between the specified pair of registers.  This macro must
02120    be defined if `ELIMINABLE_REGS' is defined.  */
02121 
02122 /* See frv_stack_info for more details on the frv stack frame.  */
02123 
02124 int
02125 frv_initial_elimination_offset (int from, int to)
02126 {
02127   frv_stack_t *info = frv_stack_info ();
02128   int ret = 0;
02129 
02130   if (to == STACK_POINTER_REGNUM && from == ARG_POINTER_REGNUM)
02131     ret = info->total_size - info->pretend_size;
02132 
02133   else if (to == STACK_POINTER_REGNUM && from == FRAME_POINTER_REGNUM)
02134     ret = info->reg_offset[FRAME_POINTER_REGNUM];
02135 
02136   else if (to == FRAME_POINTER_REGNUM && from == ARG_POINTER_REGNUM)
02137     ret = (info->total_size
02138      - info->reg_offset[FRAME_POINTER_REGNUM]
02139      - info->pretend_size);
02140 
02141   else
02142     abort ();
02143 
02144   if (TARGET_DEBUG_STACK)
02145     fprintf (stderr, "Eliminate %s to %s by adding %d\n",
02146        reg_names [from], reg_names[to], ret);
02147 
02148   return ret;
02149 }
02150 
02151 
02152 /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
02153 
02154 static void
02155 frv_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
02156                             enum machine_mode mode,
02157                             tree type ATTRIBUTE_UNUSED,
02158                             int *pretend_size,
02159                             int second_time)
02160 {
02161   if (TARGET_DEBUG_ARG)
02162     fprintf (stderr,
02163        "setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n",
02164        *cum, GET_MODE_NAME (mode), *pretend_size, second_time);
02165 }
02166 
02167 
02168 /* Worker function for TARGET_EXPAND_BUILTIN_SAVEREGS.  */
02169 
02170 static rtx
02171 frv_expand_builtin_saveregs (void)
02172 {
02173   int offset = UNITS_PER_WORD * FRV_NUM_ARG_REGS;
02174 
02175   if (TARGET_DEBUG_ARG)
02176     fprintf (stderr, "expand_builtin_saveregs: offset from ap = %d\n",
02177        offset);
02178 
02179   return gen_rtx_PLUS (Pmode, virtual_incoming_args_rtx, GEN_INT (- offset));
02180 }
02181 
02182 
02183 /* Expand __builtin_va_start to do the va_start macro.  */
02184 
02185 void
02186 frv_expand_builtin_va_start (tree valist, rtx nextarg)
02187 {
02188   tree t;
02189   int num = cfun->args_info - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS;
02190 
02191   nextarg = gen_rtx_PLUS (Pmode, virtual_incoming_args_rtx,
02192         GEN_INT (UNITS_PER_WORD * num));
02193 
02194   if (TARGET_DEBUG_ARG)
02195     {
02196       fprintf (stderr, "va_start: args_info = %d, num = %d\n",
02197          cfun->args_info, num);
02198 
02199       debug_rtx (nextarg);
02200     }
02201 
02202   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
02203        make_tree (ptr_type_node, nextarg));
02204   TREE_SIDE_EFFECTS (t) = 1;
02205 
02206   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02207 }
02208 
02209 
02210 /* Expand a block move operation, and return 1 if successful.  Return 0
02211    if we should let the compiler generate normal code.
02212 
02213    operands[0] is the destination
02214    operands[1] is the source
02215    operands[2] is the length
02216    operands[3] is the alignment */
02217 
02218 /* Maximum number of loads to do before doing the stores */
02219 #ifndef MAX_MOVE_REG
02220 #define MAX_MOVE_REG 4
02221 #endif
02222 
02223 /* Maximum number of total loads to do.  */
02224 #ifndef TOTAL_MOVE_REG
02225 #define TOTAL_MOVE_REG 8
02226 #endif
02227 
02228 int
02229 frv_expand_block_move (rtx operands[])
02230 {
02231   rtx orig_dest = operands[0];
02232   rtx orig_src  = operands[1];
02233   rtx bytes_rtx = operands[2];
02234   rtx align_rtx = operands[3];
02235   int constp  = (GET_CODE (bytes_rtx) == CONST_INT);
02236   int align;
02237   int bytes;
02238   int offset;
02239   int num_reg;
02240   int i;
02241   rtx src_reg;
02242   rtx dest_reg;
02243   rtx src_addr;
02244   rtx dest_addr;
02245   rtx src_mem;
02246   rtx dest_mem;
02247   rtx tmp_reg;
02248   rtx stores[MAX_MOVE_REG];
02249   int move_bytes;
02250   enum machine_mode mode;
02251 
02252   /* If this is not a fixed size move, just call memcpy.  */
02253   if (! constp)
02254     return FALSE;
02255 
02256   /* If this is not a fixed size alignment, abort.  */
02257   if (GET_CODE (align_rtx) != CONST_INT)
02258     abort ();
02259 
02260   align = INTVAL (align_rtx);
02261 
02262   /* Anything to move? */
02263   bytes = INTVAL (bytes_rtx);
02264   if (bytes <= 0)
02265     return TRUE;
02266 
02267   /* Don't support real large moves.  */
02268   if (bytes > TOTAL_MOVE_REG*align)
02269     return FALSE;
02270 
02271   /* Move the address into scratch registers.  */
02272   dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
02273   src_reg  = copy_addr_to_reg (XEXP (orig_src,  0));
02274 
02275   num_reg = offset = 0;
02276   for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
02277     {
02278       /* Calculate the correct offset for src/dest.  */
02279       if (offset == 0)
02280   {
02281     src_addr  = src_reg;
02282     dest_addr = dest_reg;
02283   }
02284       else
02285   {
02286     src_addr = plus_constant (src_reg, offset);
02287     dest_addr = plus_constant (dest_reg, offset);
02288   }
02289 
02290       /* Generate the appropriate load and store, saving the stores
02291    for later.  */
02292       if (bytes >= 4 && align >= 4)
02293   mode = SImode;
02294       else if (bytes >= 2 && align >= 2)
02295   mode = HImode;
02296       else
02297   mode = QImode;
02298 
02299       move_bytes = GET_MODE_SIZE (mode);
02300       tmp_reg = gen_reg_rtx (mode);
02301       src_mem = change_address (orig_src, mode, src_addr);
02302       dest_mem = change_address (orig_dest, mode, dest_addr);
02303       emit_insn (gen_rtx_SET (VOIDmode, tmp_reg, src_mem));
02304       stores[num_reg++] = gen_rtx_SET (VOIDmode, dest_mem, tmp_reg);
02305 
02306       if (num_reg >= MAX_MOVE_REG)
02307   {
02308     for (i = 0; i < num_reg; i++)
02309       emit_insn (stores[i]);
02310     num_reg = 0;
02311   }
02312     }
02313 
02314   for (i = 0; i < num_reg; i++)
02315     emit_insn (stores[i]);
02316 
02317   return TRUE;
02318 }
02319 
02320 
02321 /* Expand a block clear operation, and return 1 if successful.  Return 0
02322    if we should let the compiler generate normal code.
02323 
02324    operands[0] is the destination
02325    operands[1] is the length
02326    operands[2] is the alignment */
02327 
02328 int
02329 frv_expand_block_clear (rtx operands[])
02330 {
02331   rtx orig_dest = operands[0];
02332   rtx bytes_rtx = operands[1];
02333   rtx align_rtx = operands[2];
02334   int constp  = (GET_CODE (bytes_rtx) == CONST_INT);
02335   int align;
02336   int bytes;
02337   int offset;
02338   int num_reg;
02339   rtx dest_reg;
02340   rtx dest_addr;
02341   rtx dest_mem;
02342   int clear_bytes;
02343   enum machine_mode mode;
02344 
02345   /* If this is not a fixed size move, just call memcpy.  */
02346   if (! constp)
02347     return FALSE;
02348 
02349   /* If this is not a fixed size alignment, abort.  */
02350   if (GET_CODE (align_rtx) != CONST_INT)
02351     abort ();
02352 
02353   align = INTVAL (align_rtx);
02354 
02355   /* Anything to move? */
02356   bytes = INTVAL (bytes_rtx);
02357   if (bytes <= 0)
02358     return TRUE;
02359 
02360   /* Don't support real large clears.  */
02361   if (bytes > TOTAL_MOVE_REG*align)
02362     return FALSE;
02363 
02364   /* Move the address into a scratch register.  */
02365   dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
02366 
02367   num_reg = offset = 0;
02368   for ( ; bytes > 0; (bytes -= clear_bytes), (offset += clear_bytes))
02369     {
02370       /* Calculate the correct offset for src/dest.  */
02371       dest_addr = ((offset == 0)
02372        ? dest_reg
02373        : plus_constant (dest_reg, offset));
02374 
02375       /* Generate the appropriate store of gr0.  */
02376       if (bytes >= 4 && align >= 4)
02377   mode = SImode;
02378       else if (bytes >= 2 && align >= 2)
02379   mode = HImode;
02380       else
02381   mode = QImode;
02382 
02383       clear_bytes = GET_MODE_SIZE (mode);
02384       dest_mem = change_address (orig_dest, mode, dest_addr);
02385       emit_insn (gen_rtx_SET (VOIDmode, dest_mem, const0_rtx));
02386     }
02387 
02388   return TRUE;
02389 }
02390 
02391 
02392 /* The following variable is used to output modifiers of assembler
02393    code of the current output insn.  */
02394 
02395 static rtx *frv_insn_operands;
02396 
02397 /* The following function is used to add assembler insn code suffix .p
02398    if it is necessary.  */
02399 
02400 const char *
02401 frv_asm_output_opcode (FILE *f, const char *ptr)
02402 {
02403   int c;
02404 
02405   if (frv_insn_packing_flag <= 0)
02406     return ptr;
02407 
02408   for (; *ptr && *ptr != ' ' && *ptr != '\t';)
02409     {
02410       c = *ptr++;
02411       if (c == '%' && ((*ptr >= 'a' && *ptr <= 'z')
02412            || (*ptr >= 'A' && *ptr <= 'Z')))
02413   {
02414     int letter = *ptr++;
02415 
02416     c = atoi (ptr);
02417     frv_print_operand (f, frv_insn_operands [c], letter);
02418     while ((c = *ptr) >= '0' && c <= '9')
02419       ptr++;
02420   }
02421       else
02422   fputc (c, f);
02423     }
02424 
02425   fprintf (f, ".p");
02426 
02427   return ptr;
02428 }
02429 
02430 /* Set up the packing bit for the current output insn.  Note that this
02431    function is not called for asm insns.  */
02432 
02433 void
02434 frv_final_prescan_insn (rtx insn, rtx *opvec,
02435       int noperands ATTRIBUTE_UNUSED)
02436 {
02437   if (INSN_P (insn))
02438     {
02439       if (frv_insn_packing_flag >= 0)
02440   {
02441     frv_insn_operands = opvec;
02442     frv_insn_packing_flag = PACKING_FLAG_P (insn);
02443   }
02444       else if (recog_memoized (insn) >= 0
02445          && get_attr_acc_group (insn) == ACC_GROUP_ODD)
02446   /* Packing optimizations have been disabled, but INSN can only
02447      be issued in M1.  Insert an mnop in M0.  */
02448   fprintf (asm_out_file, "\tmnop.p\n");
02449     }
02450 }
02451 
02452 
02453 
02454 /* A C expression whose value is RTL representing the address in a stack frame
02455    where the pointer to the caller's frame is stored.  Assume that FRAMEADDR is
02456    an RTL expression for the address of the stack frame itself.
02457 
02458    If you don't define this macro, the default is to return the value of
02459    FRAMEADDR--that is, the stack frame address is also the address of the stack
02460    word that points to the previous frame.  */
02461 
02462 /* The default is correct, but we need to make sure the frame gets created.  */
02463 rtx
02464 frv_dynamic_chain_address (rtx frame)
02465 {
02466   cfun->machine->frame_needed = 1;
02467   return frame;
02468 }
02469 
02470 
02471 /* A C expression whose value is RTL representing the value of the return
02472    address for the frame COUNT steps up from the current frame, after the
02473    prologue.  FRAMEADDR is the frame pointer of the COUNT frame, or the frame
02474    pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
02475    defined.
02476 
02477    The value of the expression must always be the correct address when COUNT is
02478    zero, but may be `NULL_RTX' if there is not way to determine the return
02479    address of other frames.  */
02480 
02481 rtx
02482 frv_return_addr_rtx (int count, rtx frame)
02483 {
02484   if (count != 0)
02485     return const0_rtx;
02486   cfun->machine->frame_needed = 1;
02487   return gen_rtx_MEM (Pmode, plus_constant (frame, 8));
02488 }
02489 
02490 /* Given a memory reference MEMREF, interpret the referenced memory as
02491    an array of MODE values, and return a reference to the element
02492    specified by INDEX.  Assume that any pre-modification implicit in
02493    MEMREF has already happened.
02494 
02495    MEMREF must be a legitimate operand for modes larger than SImode.
02496    GO_IF_LEGITIMATE_ADDRESS forbids register+register addresses, which
02497    this function cannot handle.  */
02498 rtx
02499 frv_index_memory (rtx memref, enum machine_mode mode, int index)
02500 {
02501   rtx base = XEXP (memref, 0);
02502   if (GET_CODE (base) == PRE_MODIFY)
02503     base = XEXP (base, 0);
02504   return change_address (memref, mode,
02505        plus_constant (base, index * GET_MODE_SIZE (mode)));
02506 }
02507 
02508 
02509 /* Print a memory address as an operand to reference that memory location.  */
02510 void
02511 frv_print_operand_address (FILE * stream, rtx x)
02512 {
02513   if (GET_CODE (x) == MEM)
02514     x = XEXP (x, 0);
02515 
02516   switch (GET_CODE (x))
02517     {
02518     case REG:
02519       fputs (reg_names [ REGNO (x)], stream);
02520       return;
02521 
02522     case CONST_INT:
02523       fprintf (stream, "%ld", (long) INTVAL (x));
02524       return;
02525 
02526     case SYMBOL_REF:
02527       assemble_name (stream, XSTR (x, 0));
02528       return;
02529 
02530     case LABEL_REF:
02531     case CONST:
02532       output_addr_const (stream, x);
02533       return;
02534 
02535     default:
02536       break;
02537     }
02538 
02539   fatal_insn ("Bad insn to frv_print_operand_address:", x);
02540 }
02541 
02542 
02543 static void
02544 frv_print_operand_memory_reference_reg (FILE * stream, rtx x)
02545 {
02546   int regno = true_regnum (x);
02547   if (GPR_P (regno))
02548     fputs (reg_names[regno], stream);
02549   else
02550     fatal_insn ("Bad register to frv_print_operand_memory_reference_reg:", x);
02551 }
02552 
02553 /* Print a memory reference suitable for the ld/st instructions.  */
02554 
02555 static void
02556 frv_print_operand_memory_reference (FILE * stream, rtx x, int addr_offset)
02557 {
02558   struct frv_unspec unspec;
02559   rtx x0 = NULL_RTX;
02560   rtx x1 = NULL_RTX;
02561 
02562   switch (GET_CODE (x))
02563     {
02564     case SUBREG:
02565     case REG:
02566       x0 = x;
02567       break;
02568 
02569     case PRE_MODIFY:    /* (pre_modify (reg) (plus (reg) (reg))) */
02570       x0 = XEXP (x, 0);
02571       x1 = XEXP (XEXP (x, 1), 1);
02572       break;
02573 
02574     case CONST_INT:
02575       x1 = x;
02576       break;
02577 
02578     case PLUS:
02579       x0 = XEXP (x, 0);
02580       x1 = XEXP (x, 1);
02581       if (GET_CODE (x0) == CONST_INT)
02582   {
02583     x0 = XEXP (x, 1);
02584     x1 = XEXP (x, 0);
02585   }
02586       break;
02587 
02588     default:
02589       fatal_insn ("Bad insn to frv_print_operand_memory_reference:", x);
02590       break;
02591 
02592     }
02593 
02594   if (addr_offset)
02595     {
02596       if (!x1)
02597   x1 = const0_rtx;
02598       else if (GET_CODE (x1) != CONST_INT)
02599   fatal_insn ("Bad insn to frv_print_operand_memory_reference:", x);
02600     }
02601 
02602   fputs ("@(", stream);
02603   if (!x0)
02604     fputs (reg_names[GPR_R0], stream);
02605   else if (GET_CODE (x0) == REG || GET_CODE (x0) == SUBREG)
02606     frv_print_operand_memory_reference_reg (stream, x0);
02607   else
02608     fatal_insn ("Bad insn to frv_print_operand_memory_reference:", x);
02609 
02610   fputs (",", stream);
02611   if (!x1)
02612     fputs (reg_names [GPR_R0], stream);
02613 
02614   else
02615     {
02616       switch (GET_CODE (x1))
02617   {
02618   case SUBREG:
02619   case REG:
02620     frv_print_operand_memory_reference_reg (stream, x1);
02621     break;
02622 
02623   case CONST_INT:
02624     fprintf (stream, "%ld", (long) (INTVAL (x1) + addr_offset));
02625     break;
02626 
02627   case CONST:
02628     if (!frv_const_unspec_p (x1, &unspec))
02629       fatal_insn ("Bad insn to frv_print_operand_memory_reference:", x1);
02630     frv_output_const_unspec (stream, &unspec);
02631     break;
02632 
02633   default:
02634     fatal_insn ("Bad insn to frv_print_operand_memory_reference:", x);
02635   }
02636     }
02637 
02638   fputs (")", stream);
02639 }
02640 
02641 
02642 /* Return 2 for likely branches and 0 for non-likely branches  */
02643 
02644 #define FRV_JUMP_LIKELY 2
02645 #define FRV_JUMP_NOT_LIKELY 0
02646 
02647 static int
02648 frv_print_operand_jump_hint (rtx insn)
02649 {
02650   rtx note;
02651   rtx labelref;
02652   int ret;
02653   HOST_WIDE_INT prob = -1;
02654   enum { UNKNOWN, BACKWARD, FORWARD } jump_type = UNKNOWN;
02655 
02656   if (GET_CODE (insn) != JUMP_INSN)
02657     abort ();
02658 
02659   /* Assume any non-conditional jump is likely.  */
02660   if (! any_condjump_p (insn))
02661     ret = FRV_JUMP_LIKELY;
02662 
02663   else
02664     {
02665       labelref = condjump_label (insn);
02666       if (labelref)
02667   {
02668     rtx label = XEXP (labelref, 0);
02669     jump_type = (insn_current_address > INSN_ADDRESSES (INSN_UID (label))
02670            ? BACKWARD
02671            : FORWARD);
02672   }
02673 
02674       note = find_reg_note (insn, REG_BR_PROB, 0);
02675       if (!note)
02676   ret = ((jump_type == BACKWARD) ? FRV_JUMP_LIKELY : FRV_JUMP_NOT_LIKELY);
02677 
02678       else
02679   {
02680     prob = INTVAL (XEXP (note, 0));
02681     ret = ((prob >= (REG_BR_PROB_BASE / 2))
02682      ? FRV_JUMP_LIKELY
02683      : FRV_JUMP_NOT_LIKELY);
02684   }
02685     }
02686 
02687 #if 0
02688   if (TARGET_DEBUG)
02689     {
02690       char *direction;
02691 
02692       switch (jump_type)
02693   {
02694   default:
02695   case UNKNOWN: direction = "unknown jump direction"; break;
02696   case BACKWARD:  direction = "jump backward";    break;
02697   case FORWARD: direction = "jump forward";   break;
02698   }
02699 
02700       fprintf (stderr,
02701          "%s: uid %ld, %s, probability = %ld, max prob. = %ld, hint = %d\n",
02702          IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
02703          (long)INSN_UID (insn), direction, (long)prob,
02704          (long)REG_BR_PROB_BASE, ret);
02705     }
02706 #endif
02707 
02708   return ret;
02709 }
02710 
02711 
02712 /* Return the comparison operator to use for CODE given that the ICC
02713    register is OP0.  */
02714 
02715 static const char *
02716 comparison_string (enum rtx_code code, rtx op0)
02717 {
02718   bool is_nz_p = GET_MODE (op0) == CC_NZmode;
02719   switch (code)
02720     {
02721     default:  output_operand_lossage ("bad condition code");
02722     case EQ:  return "eq";
02723     case NE:  return "ne";
02724     case LT:  return is_nz_p ? "n" : "lt";
02725     case LE:  return "le";
02726     case GT:  return "gt";
02727     case GE:  return is_nz_p ? "p" : "ge";
02728     case LTU: return is_nz_p ? "no" : "c";
02729     case LEU: return is_nz_p ? "eq" : "ls";
02730     case GTU: return is_nz_p ? "ne" : "hi";
02731     case GEU: return is_nz_p ? "ra" : "nc";
02732     }
02733 }
02734 
02735 /* Print an operand to an assembler instruction.
02736 
02737    `%' followed by a letter and a digit says to output an operand in an
02738    alternate fashion.  Four letters have standard, built-in meanings described
02739    below.  The machine description macro `PRINT_OPERAND' can define additional
02740    letters with nonstandard meanings.
02741 
02742    `%cDIGIT' can be used to substitute an operand that is a constant value
02743    without the syntax that normally indicates an immediate operand.
02744 
02745    `%nDIGIT' is like `%cDIGIT' except that the value of the constant is negated
02746    before printing.
02747 
02748    `%aDIGIT' can be used to substitute an operand as if it were a memory
02749    reference, with the actual operand treated as the address.  This may be
02750    useful when outputting a "load address" instruction, because often the
02751    assembler syntax for such an instruction requires you to write the operand
02752    as if it were a memory reference.
02753 
02754    `%lDIGIT' is used to substitute a `label_ref' into a jump instruction.
02755 
02756    `%=' outputs a number which is unique to each instruction in the entire
02757    compilation.  This is useful for making local labels to be referred to more
02758    than once in a single template that generates multiple assembler
02759    instructions.
02760 
02761    `%' followed by a punctuation character specifies a substitution that does
02762    not use an operand.  Only one case is standard: `%%' outputs a `%' into the
02763    assembler code.  Other nonstandard cases can be defined in the
02764    `PRINT_OPERAND' macro.  You must also define which punctuation characters
02765    are valid with the `PRINT_OPERAND_PUNCT_VALID_P' macro.  */
02766 
02767 void
02768 frv_print_operand (FILE * file, rtx x, int code)
02769 {
02770   struct frv_unspec unspec;
02771   HOST_WIDE_INT value;
02772   int offset;
02773 
02774   if (code != 0 && !isalpha (code))
02775     value = 0;
02776 
02777   else if (GET_CODE (x) == CONST_INT)
02778     value = INTVAL (x);
02779 
02780   else if (GET_CODE (x) == CONST_DOUBLE)
02781     {
02782       if (GET_MODE (x) == SFmode)
02783   {
02784     REAL_VALUE_TYPE rv;
02785     long l;
02786 
02787     REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
02788     REAL_VALUE_TO_TARGET_SINGLE (rv, l);
02789     value = l;
02790   }
02791 
02792       else if (GET_MODE (x) == VOIDmode)
02793   value = CONST_DOUBLE_LOW (x);
02794 
02795       else
02796         fatal_insn ("Bad insn in frv_print_operand, bad const_double", x);
02797     }
02798 
02799   else
02800     value = 0;
02801 
02802   switch (code)
02803     {
02804 
02805     case '.':
02806       /* Output r0.  */
02807       fputs (reg_names[GPR_R0], file);
02808       break;
02809 
02810     case '#':
02811       fprintf (file, "%d", frv_print_operand_jump_hint (current_output_insn));
02812       break;
02813 
02814     case '@':
02815       /* Output small data area base register (gr16).  */
02816       fputs (reg_names[SDA_BASE_REG], file);
02817       break;
02818 
02819     case '~':
02820       /* Output pic register (gr17).  */
02821       fputs (reg_names[PIC_REGNO], file);
02822       break;
02823 
02824     case '*':
02825       /* Output the temporary integer CCR register.  */
02826       fputs (reg_names[ICR_TEMP], file);
02827       break;
02828 
02829     case '&':
02830       /* Output the temporary integer CC register.  */
02831       fputs (reg_names[ICC_TEMP], file);
02832       break;
02833 
02834     /* case 'a': print an address.  */
02835 
02836     case 'C':
02837       /* Print appropriate test for integer branch false operation.  */
02838       fputs (comparison_string (reverse_condition (GET_CODE (x)),
02839         XEXP (x, 0)), file);
02840       break;
02841 
02842     case 'c':
02843       /* Print appropriate test for integer branch true operation.  */
02844       fputs (comparison_string (GET_CODE (x), XEXP (x, 0)), file);
02845       break;
02846 
02847     case 'e':
02848       /* Print 1 for a NE and 0 for an EQ to give the final argument
02849    for a conditional instruction.  */
02850       if (GET_CODE (x) == NE)
02851   fputs ("1", file);
02852 
02853       else if (GET_CODE (x) == EQ)
02854   fputs ("0", file);
02855 
02856       else
02857   fatal_insn ("Bad insn to frv_print_operand, 'e' modifier:", x);
02858       break;
02859 
02860     case 'F':
02861       /* Print appropriate test for floating point branch false operation.  */
02862       switch (GET_CODE (x))
02863   {
02864   default:
02865     fatal_insn ("Bad insn to frv_print_operand, 'F' modifier:", x);
02866 
02867   case EQ:  fputs ("ne",  file); break;
02868   case NE:  fputs ("eq",  file); break;
02869   case LT:  fputs ("uge", file); break;
02870   case LE:  fputs ("ug",  file); break;
02871   case GT:  fputs ("ule", file); break;
02872   case GE:  fputs ("ul",  file); break;
02873   }
02874       break;
02875 
02876     case 'f':
02877       /* Print appropriate test for floating point branch true operation.  */
02878       switch (GET_CODE (x))
02879   {
02880   default:
02881     fatal_insn ("Bad insn to frv_print_operand, 'f' modifier:", x);
02882 
02883   case EQ:  fputs ("eq",  file); break;
02884   case NE:  fputs ("ne",  file); break;
02885   case LT:  fputs ("lt",  file); break;
02886   case LE:  fputs ("le",  file); break;
02887   case GT:  fputs ("gt",  file); break;
02888   case GE:  fputs ("ge",  file); break;
02889   }
02890       break;
02891 
02892     case 'g':
02893       /* Print appropriate GOT function.  */
02894       if (GET_CODE (x) != CONST_INT)
02895   fatal_insn ("Bad insn to frv_print_operand, 'g' modifier:", x);
02896       fputs (unspec_got_name (INTVAL (x)), file);
02897       break;
02898 
02899     case 'I':
02900       /* Print 'i' if the operand is a constant, or is a memory reference that
02901          adds a constant.  */
02902       if (GET_CODE (x) == MEM)
02903   x = ((GET_CODE (XEXP (x, 0)) == PLUS)
02904        ? XEXP (XEXP (x, 0), 1)
02905        : XEXP (x, 0));
02906       else if (GET_CODE (x) == PLUS)
02907   x = XEXP (x, 1);
02908 
02909       switch (GET_CODE (x))
02910   {
02911   default:
02912     break;
02913 
02914   case CONST_INT:
02915   case SYMBOL_REF:
02916   case CONST:
02917     fputs ("i", file);
02918     break;
02919   }
02920       break;
02921 
02922     case 'i':
02923       /* For jump instructions, print 'i' if the operand is a constant or
02924          is an expression that adds a constant.  */
02925       if (GET_CODE (x) == CONST_INT)
02926         fputs ("i", file);
02927 
02928       else
02929         {
02930           if (GET_CODE (x) == CONST_INT
02931               || (GET_CODE (x) == PLUS
02932                   && (GET_CODE (XEXP (x, 1)) == CONST_INT
02933                       || GET_CODE (XEXP (x, 0)) == CONST_INT)))
02934             fputs ("i", file);
02935         }
02936       break;
02937 
02938     case 'L':
02939       /* Print the lower register of a double word register pair */
02940       if (GET_CODE (x) == REG)
02941   fputs (reg_names[ REGNO (x)+1 ], file);
02942       else
02943   fatal_insn ("Bad insn to frv_print_operand, 'L' modifier:", x);
02944       break;
02945 
02946     /* case 'l': print a LABEL_REF.  */
02947 
02948     case 'M':
02949     case 'N':
02950       /* Print a memory reference for ld/st/jmp, %N prints a memory reference
02951          for the second word of double memory operations.  */
02952       offset = (code == 'M') ? 0 : UNITS_PER_WORD;
02953       switch (GET_CODE (x))
02954   {
02955   default:
02956     fatal_insn ("Bad insn to frv_print_operand, 'M/N' modifier:", x);
02957 
02958   case MEM:
02959     frv_print_operand_memory_reference (file, XEXP (x, 0), offset);
02960     break;
02961 
02962   case REG:
02963   case SUBREG:
02964   case CONST_INT:
02965   case PLUS:
02966         case SYMBOL_REF:
02967     frv_print_operand_memory_reference (file, x, offset);
02968     break;
02969   }
02970       break;
02971 
02972     case 'O':
02973       /* Print the opcode of a command.  */
02974       switch (GET_CODE (x))
02975   {
02976   default:
02977     fatal_insn ("Bad insn to frv_print_operand, 'O' modifier:", x);
02978 
02979   case PLUS:     fputs ("add", file); break;
02980   case MINUS:    fputs ("sub", file); break;
02981   case AND:      fputs ("and", file); break;
02982   case IOR:      fputs ("or",  file); break;
02983   case XOR:      fputs ("xor", file); break;
02984   case ASHIFT:   fputs ("sll", file); break;
02985   case ASHIFTRT: fputs ("sra", file); break;
02986   case LSHIFTRT: fputs ("srl", file); break;
02987   }
02988       break;
02989 
02990     /* case 'n': negate and print a constant int.  */
02991 
02992     case 'P':
02993       /* Print PIC label using operand as the number.  */
02994       if (GET_CODE (x) != CONST_INT)
02995   fatal_insn ("Bad insn to frv_print_operand, P modifier:", x);
02996 
02997       fprintf (file, ".LCF%ld", (long)INTVAL (x));
02998       break;
02999 
03000     case 'U':
03001       /* Print 'u' if the operand is a update load/store.  */
03002       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
03003   fputs ("u", file);
03004       break;
03005 
03006     case 'z':
03007       /* If value is 0, print gr0, otherwise it must be a register.  */
03008       if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
03009   fputs (reg_names[GPR_R0], file);
03010 
03011       else if (GET_CODE (x) == REG)
03012         fputs (reg_names [REGNO (x)], file);
03013 
03014       else
03015         fatal_insn ("Bad insn in frv_print_operand, z case", x);
03016       break;
03017 
03018     case 'x':
03019       /* Print constant in hex.  */
03020       if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
03021         {
03022     fprintf (file, "%s0x%.4lx", IMMEDIATE_PREFIX, (long) value);
03023     break;
03024   }
03025 
03026       /* Fall through.  */
03027 
03028     case '\0':
03029       if (GET_CODE (x) == REG)
03030         fputs (reg_names [REGNO (x)], file);
03031 
03032       else if (GET_CODE (x) == CONST_INT
03033               || GET_CODE (x) == CONST_DOUBLE)
03034         fprintf (file, "%s%ld", IMMEDIATE_PREFIX, (long) value);
03035 
03036       else if (frv_const_unspec_p (x, &unspec))
03037   frv_output_const_unspec (file, &unspec);
03038 
03039       else if (GET_CODE (x) == MEM)
03040         frv_print_operand_address (file, XEXP (x, 0));
03041 
03042       else if (CONSTANT_ADDRESS_P (x))
03043         frv_print_operand_address (file, x);
03044 
03045       else
03046         fatal_insn ("Bad insn in frv_print_operand, 0 case", x);
03047 
03048       break;
03049 
03050     default:
03051       fatal_insn ("frv_print_operand: unknown code", x);
03052       break;
03053     }
03054 
03055   return;
03056 }
03057 
03058 
03059 /* A C statement (sans semicolon) for initializing the variable CUM for the
03060    state at the beginning of the argument list.  The variable has type
03061    `CUMULATIVE_ARGS'.  The value of FNTYPE is the tree node for the data type
03062    of the function which will receive the args, or 0 if the args are to a
03063    compiler support library function.  The value of INDIRECT is nonzero when
03064    processing an indirect call, for example a call through a function pointer.
03065    The value of INDIRECT is zero for a call to an explicitly named function, a
03066    library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
03067    arguments for the function being compiled.
03068 
03069    When processing a call to a compiler support library function, LIBNAME
03070    identifies which one.  It is a `symbol_ref' rtx which contains the name of
03071    the function, as a string.  LIBNAME is 0 when an ordinary C function call is
03072    being processed.  Thus, each time this macro is called, either LIBNAME or
03073    FNTYPE is nonzero, but never both of them at once.  */
03074 
03075 void
03076 frv_init_cumulative_args (CUMULATIVE_ARGS *cum,
03077                           tree fntype,
03078                           rtx libname,
03079                           tree fndecl,
03080                           int incoming)
03081 {
03082   *cum = FIRST_ARG_REGNUM;
03083 
03084   if (TARGET_DEBUG_ARG)
03085     {
03086       fprintf (stderr, "\ninit_cumulative_args:");
03087       if (!fndecl && fntype)
03088   fputs (" indirect", stderr);
03089 
03090       if (incoming)
03091   fputs (" incoming", stderr);
03092 
03093       if (fntype)
03094   {
03095     tree ret_type = TREE_TYPE (fntype);
03096     fprintf (stderr, " return=%s,",
03097        tree_code_name[ (int)TREE_CODE (ret_type) ]);
03098   }
03099 
03100       if (libname && GET_CODE (libname) == SYMBOL_REF)
03101   fprintf (stderr, " libname=%s", XSTR (libname, 0));
03102 
03103       if (cfun->returns_struct)
03104   fprintf (stderr, " return-struct");
03105 
03106       putc ('\n', stderr);
03107     }
03108 }
03109 
03110 
03111 /* Return true if we should pass an argument on the stack rather than
03112    in registers.  */
03113 
03114 static bool
03115 frv_must_pass_in_stack (enum machine_mode mode, tree type)
03116 {
03117   if (mode == BLKmode)
03118     return true;
03119   if (type == NULL)
03120     return false;
03121   return AGGREGATE_TYPE_P (type);
03122 }
03123 
03124 /* If defined, a C expression that gives the alignment boundary, in bits, of an
03125    argument with the specified mode and type.  If it is not defined,
03126    `PARM_BOUNDARY' is used for all arguments.  */
03127 
03128 int
03129 frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
03130                            tree type ATTRIBUTE_UNUSED)
03131 {
03132   return BITS_PER_WORD;
03133 }
03134 
03135 rtx
03136 frv_function_arg (CUMULATIVE_ARGS *cum,
03137                   enum machine_mode mode,
03138                   tree type ATTRIBUTE_UNUSED,
03139                   int named,
03140                   int incoming ATTRIBUTE_UNUSED)
03141 {
03142   enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
03143   int arg_num = *cum;
03144   rtx ret;
03145   const char *debstr;
03146 
03147   /* Return a marker for use in the call instruction.  */
03148   if (xmode == VOIDmode)
03149     {
03150       ret = const0_rtx;
03151       debstr = "<0>";
03152     }
03153 
03154   else if (arg_num <= LAST_ARG_REGNUM)
03155     {
03156       ret = gen_rtx_REG (xmode, arg_num);
03157       debstr = reg_names[arg_num];
03158     }
03159 
03160   else
03161     {
03162       ret = NULL_RTX;
03163       debstr = "memory";
03164     }
03165 
03166   if (TARGET_DEBUG_ARG)
03167     fprintf (stderr,
03168        "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n",
03169        arg_num, GET_MODE_NAME (mode), named, GET_MODE_SIZE (mode), debstr);
03170 
03171   return ret;
03172 }
03173 
03174 
03175 /* A C statement (sans semicolon) to update the summarizer variable CUM to
03176    advance past an argument in the argument list.  The values MODE, TYPE and
03177    NAMED describe that argument.  Once this is done, the variable CUM is
03178    suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
03179 
03180    This macro need not do anything if the argument in question was passed on
03181    the stack.  The compiler knows how to track the amount of stack space used
03182    for arguments without any special help.  */
03183 
03184 void
03185 frv_function_arg_advance (CUMULATIVE_ARGS *cum,
03186                           enum machine_mode mode,
03187                           tree type ATTRIBUTE_UNUSED,
03188                           int named)
03189 {
03190   enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
03191   int bytes = GET_MODE_SIZE (xmode);
03192   int words = (bytes + UNITS_PER_WORD  - 1) / UNITS_PER_WORD;
03193   int arg_num = *cum;
03194 
03195   *cum = arg_num + words;
03196 
03197   if (TARGET_DEBUG_ARG)
03198     fprintf (stderr,
03199        "function_adv: words = %2d, mode = %4s, named = %d, size = %3d\n",
03200        arg_num, GET_MODE_NAME (mode), named, words * UNITS_PER_WORD);
03201 }
03202 
03203 
03204 /* A C expression for the number of words, at the beginning of an argument,
03205    must be put in registers.  The value must be zero for arguments that are
03206    passed entirely in registers or that are entirely pushed on the stack.
03207 
03208    On some machines, certain arguments must be passed partially in registers
03209    and partially in memory.  On these machines, typically the first N words of
03210    arguments are passed in registers, and the rest on the stack.  If a
03211    multi-word argument (a `double' or a structure) crosses that boundary, its
03212    first few words must be passed in registers and the rest must be pushed.
03213    This macro tells the compiler when this occurs, and how many of the words
03214    should go in registers.
03215 
03216    `FUNCTION_ARG' for these arguments should return the first register to be
03217    used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
03218    the called function.  */
03219 
03220 static int
03221 frv_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
03222            tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
03223 {
03224   enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
03225   int bytes = GET_MODE_SIZE (xmode);
03226   int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
03227   int arg_num = *cum;
03228   int ret;
03229 
03230   ret = ((arg_num <= LAST_ARG_REGNUM && arg_num + words > LAST_ARG_REGNUM+1)
03231    ? LAST_ARG_REGNUM - arg_num + 1
03232    : 0);
03233   ret *= UNITS_PER_WORD;
03234 
03235   if (TARGET_DEBUG_ARG && ret)
03236     fprintf (stderr, "frv_arg_partial_bytes: %d\n", ret);
03237 
03238   return ret;
03239 }
03240 
03241 
03242 /* Return true if a register is ok to use as a base or index register.  */
03243 
03244 static FRV_INLINE int
03245 frv_regno_ok_for_base_p (int regno, int strict_p)
03246 {
03247   if (GPR_P (regno))
03248     return TRUE;
03249 
03250   if (strict_p)
03251     return (reg_renumber[regno] >= 0 && GPR_P (reg_renumber[regno]));
03252 
03253   if (regno == ARG_POINTER_REGNUM)
03254     return TRUE;
03255 
03256   return (regno >= FIRST_PSEUDO_REGISTER);
03257 }
03258 
03259 
03260 /* A C compound statement with a conditional `goto LABEL;' executed if X (an
03261    RTX) is a legitimate memory address on the target machine for a memory
03262    operand of mode MODE.
03263 
03264    It usually pays to define several simpler macros to serve as subroutines for
03265    this one.  Otherwise it may be too complicated to understand.
03266 
03267    This macro must exist in two variants: a strict variant and a non-strict
03268    one.  The strict variant is used in the reload pass.  It must be defined so
03269    that any pseudo-register that has not been allocated a hard register is
03270    considered a memory reference.  In contexts where some kind of register is
03271    required, a pseudo-register with no hard register must be rejected.
03272 
03273    The non-strict variant is used in other passes.  It must be defined to
03274    accept all pseudo-registers in every context where some kind of register is
03275    required.
03276 
03277    Compiler source files that want to use the strict variant of this macro
03278    define the macro `REG_OK_STRICT'.  You should use an `#ifdef REG_OK_STRICT'
03279    conditional to define the strict variant in that case and the non-strict
03280    variant otherwise.
03281 
03282    Subroutines to check for acceptable registers for various purposes (one for
03283    base registers, one for index registers, and so on) are typically among the
03284    subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'.  Then only these
03285    subroutine macros need have two variants; the higher levels of macros may be
03286    the same whether strict or not.
03287 
03288    Normally, constant addresses which are the sum of a `symbol_ref' and an
03289    integer are stored inside a `const' RTX to mark them as constant.
03290    Therefore, there is no need to recognize such sums specifically as
03291    legitimate addresses.  Normally you would simply recognize any `const' as
03292    legitimate.
03293 
03294    Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
03295    are not marked with `const'.  It assumes that a naked `plus' indicates
03296    indexing.  If so, then you *must* reject such naked constant sums as
03297    illegitimate addresses, so that none of them will be given to
03298    `PRINT_OPERAND_ADDRESS'.
03299 
03300    On some machines, whether a symbolic address is legitimate depends on the
03301    section that the address refers to.  On these machines, define the macro
03302    `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
03303    then check for it here.  When you see a `const', you will have to look
03304    inside it to find the `symbol_ref' in order to determine the section.
03305 
03306    The best way to modify the name string is by adding text to the beginning,
03307    with suitable punctuation to prevent any ambiguity.  Allocate the new name
03308    in `saveable_obstack'.  You will have to modify `ASM_OUTPUT_LABELREF' to
03309    remove and decode the added text and output the name accordingly, and define
03310    `(* targetm.strip_name_encoding)' to access the original name string.
03311 
03312    You can check the information stored here into the `symbol_ref' in the
03313    definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
03314    `PRINT_OPERAND_ADDRESS'.  */
03315 
03316 int
03317 frv_legitimate_address_p (enum machine_mode mode,
03318                           rtx x,
03319                           int strict_p,
03320                           int condexec_p,
03321         int allow_double_reg_p)
03322 {
03323   rtx x0, x1;
03324   int ret = 0;
03325   HOST_WIDE_INT value;
03326   unsigned regno0;
03327 
03328   if (FRV_SYMBOL_REF_TLS_P (x))
03329     return 0;
03330 
03331   switch (GET_CODE (x))
03332     {
03333     default:
03334       break;
03335 
03336     case SUBREG:
03337       x = SUBREG_REG (x);
03338       if (GET_CODE (x) != REG)
03339         break;
03340 
03341       /* Fall through.  */
03342 
03343     case REG:
03344       ret = frv_regno_ok_for_base_p (REGNO (x), strict_p);
03345       break;
03346 
03347     case PRE_MODIFY:
03348       x0 = XEXP (x, 0);
03349       x1 = XEXP (x, 1);
03350       if (GET_CODE (x0) != REG
03351     || ! frv_regno_ok_for_base_p (REGNO (x0), strict_p)
03352     || GET_CODE (x1) != PLUS
03353     || ! rtx_equal_p (x0, XEXP (x1, 0))
03354     || GET_CODE (XEXP (x1, 1)) != REG
03355     || ! frv_regno_ok_for_base_p (REGNO (XEXP (x1, 1)), strict_p))
03356   break;
03357 
03358       ret = 1;
03359       break;
03360 
03361     case CONST_INT:
03362       /* 12 bit immediate */
03363       if (condexec_p)
03364   ret = FALSE;
03365       else
03366   {
03367     ret = IN_RANGE_P (INTVAL (x), -2048, 2047);
03368 
03369     /* If we can't use load/store double operations, make sure we can
03370        address the second word.  */
03371     if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
03372       ret = IN_RANGE_P (INTVAL (x) + GET_MODE_SIZE (mode) - 1,
03373             -2048, 2047);
03374   }
03375       break;
03376 
03377     case PLUS:
03378       x0 = XEXP (x, 0);
03379       x1 = XEXP (x, 1);
03380 
03381       if (GET_CODE (x0) == SUBREG)
03382   x0 = SUBREG_REG (x0);
03383 
03384       if (GET_CODE (x0) != REG)
03385   break;
03386 
03387       regno0 = REGNO (x0);
03388       if (!frv_regno_ok_for_base_p (regno0, strict_p))
03389   break;
03390 
03391       switch (GET_CODE (x1))
03392   {
03393   default:
03394     break;
03395 
03396   case SUBREG:
03397     x1 = SUBREG_REG (x1);
03398     if (GET_CODE (x1) != REG)
03399       break;
03400 
03401     /* Fall through.  */
03402 
03403   case REG:
03404     /* Do not allow reg+reg addressing for modes > 1 word if we
03405        can't depend on having move double instructions.  */
03406     if (!allow_double_reg_p && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
03407       ret = FALSE;
03408     else
03409       ret = frv_regno_ok_for_base_p (REGNO (x1), strict_p);
03410     break;
03411 
03412   case CONST_INT:
03413           /* 12 bit immediate */
03414     if (condexec_p)
03415       ret = FALSE;
03416     else
03417       {
03418         value = INTVAL (x1);
03419         ret = IN_RANGE_P (value, -2048, 2047);
03420 
03421         /* If we can't use load/store double operations, make sure we can
03422      address the second word.  */
03423         if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
03424     ret = IN_RANGE_P (value + GET_MODE_SIZE (mode) - 1, -2048, 2047);
03425       }
03426     break;
03427 
03428   case CONST:
03429     if (!condexec_p && got12_operand (x1, VOIDmode))
03430       ret = TRUE;
03431     break;
03432 
03433   }
03434       break;
03435     }
03436 
03437   if (TARGET_DEBUG_ADDR)
03438     {
03439       fprintf (stderr, "\n========== GO_IF_LEGITIMATE_ADDRESS, mode = %s, result = %d, addresses are %sstrict%s\n",
03440          GET_MODE_NAME (mode), ret, (strict_p) ? "" : "not ",
03441          (condexec_p) ? ", inside conditional code" : "");
03442       debug_rtx (x);
03443     }
03444 
03445   return ret;
03446 }
03447 
03448 /* Given an ADDR, generate code to inline the PLT.  */
03449 static rtx
03450 gen_inlined_tls_plt (rtx addr)
03451 {
03452   rtx mem, retval, dest;
03453   rtx picreg = get_hard_reg_initial_val (Pmode, FDPIC_REG);
03454 
03455 
03456   dest = gen_reg_rtx (DImode);
03457 
03458   if (flag_pic == 1)
03459     {
03460       /*
03461   -fpic version:
03462 
03463   lddi.p  @(gr15, #gottlsdesc12(ADDR)), gr8
03464   calll    #gettlsoff(ADDR)@(gr8, gr0)
03465       */
03466       emit_insn (gen_tls_lddi (dest, addr, picreg));
03467     }
03468   else
03469     {
03470       /*
03471   -fPIC version:
03472 
03473   sethi.p #gottlsdeschi(ADDR), gr8
03474   setlo   #gottlsdesclo(ADDR), gr8
03475   ldd     #tlsdesc(ADDR)@(gr15, gr8), gr8
03476   calll   #gettlsoff(ADDR)@(gr8, gr0)
03477       */
03478       rtx reguse = gen_reg_rtx (Pmode);
03479       emit_insn (gen_tlsoff_hilo (reguse, addr, GEN_INT (R_FRV_GOTTLSDESCHI)));
03480       emit_insn (gen_tls_tlsdesc_ldd (dest, picreg, reguse, addr));
03481     }
03482 
03483   retval = gen_reg_rtx (Pmode);
03484   emit_insn (gen_tls_indirect_call (retval, addr, dest, picreg));
03485   return retval;
03486 }
03487 
03488 /* Emit a TLSMOFF or TLSMOFF12 offset, depending on -mTLS.  Returns
03489    the destination address.  */
03490 static rtx
03491 gen_tlsmoff (rtx addr, rtx reg)
03492 {
03493   rtx dest = gen_reg_rtx (Pmode);
03494 
03495   if (TARGET_BIG_TLS)
03496     {
03497       /* sethi.p #tlsmoffhi(x), grA
03498    setlo   #tlsmofflo(x), grA
03499       */
03500       dest = gen_reg_rtx (Pmode);
03501       emit_insn (gen_tlsoff_hilo (dest, addr,
03502           GEN_INT (R_FRV_TLSMOFFHI)));
03503       dest = gen_rtx_PLUS (Pmode, dest, reg);
03504     }
03505   else
03506     {
03507       /* addi grB, #tlsmoff12(x), grC
03508      -or-
03509    ld/st @(grB, #tlsmoff12(x)), grC
03510       */
03511       dest = gen_reg_rtx (Pmode);
03512       emit_insn (gen_symGOTOFF2reg_i (dest, addr, reg,
03513               GEN_INT (R_FRV_TLSMOFF12)));
03514     }
03515   return dest;
03516 }
03517 
03518 /* Generate code for a TLS address.  */
03519 static rtx
03520 frv_legitimize_tls_address (rtx addr, enum tls_model model)
03521 {
03522   rtx dest, tp = gen_rtx_REG (Pmode, 29);
03523   rtx picreg = get_hard_reg_initial_val (Pmode, 15);
03524 
03525   switch (model)
03526     {
03527     case TLS_MODEL_INITIAL_EXEC:
03528       if (flag_pic == 1)
03529   {
03530     /* -fpic version.
03531        ldi @(gr15, #gottlsoff12(x)), gr5
03532      */
03533     dest = gen_reg_rtx (Pmode);
03534     emit_insn (gen_tls_load_gottlsoff12 (dest, addr, picreg));
03535     dest = gen_rtx_PLUS (Pmode, tp, dest);
03536   }
03537       else
03538   {
03539     /* -fPIC or anything else.
03540 
03541       sethi.p #gottlsoffhi(x), gr14
03542       setlo   #gottlsofflo(x), gr14
03543       ld      #tlsoff(x)@(gr15, gr14), gr9
03544     */
03545     rtx tmp = gen_reg_rtx (Pmode);
03546     dest = gen_reg_rtx (Pmode);
03547     emit_insn (gen_tlsoff_hilo (tmp, addr,
03548               GEN_INT (R_FRV_GOTTLSOFF_HI)));
03549 
03550     emit_insn (gen_tls_tlsoff_ld (dest, picreg, tmp, addr));
03551     dest = gen_rtx_PLUS (Pmode, tp, dest);
03552   }
03553       break;
03554     case TLS_MODEL_LOCAL_DYNAMIC:
03555       {
03556   rtx reg, retval;
03557 
03558   if (TARGET_INLINE_PLT)
03559     retval = gen_inlined_tls_plt (GEN_INT (0));
03560   else
03561     {
03562       /* call #gettlsoff(0) */
03563       retval = gen_reg_rtx (Pmode);
03564       emit_insn (gen_call_gettlsoff (retval, GEN_INT (0), picreg));
03565     }
03566 
03567   reg = gen_reg_rtx (Pmode);
03568   emit_insn (gen_rtx_SET (VOIDmode, reg,
03569         gen_rtx_PLUS (Pmode,
03570                 retval, tp)));
03571 
03572   dest = gen_tlsmoff (addr, reg);
03573 
03574   /*
03575   dest = gen_reg_rtx (Pmode);
03576   emit_insn (gen_tlsoff_hilo (dest, addr,
03577             GEN_INT (R_FRV_TLSMOFFHI)));
03578   dest = gen_rtx_PLUS (Pmode, dest, reg);
03579   */
03580   break;
03581       }
03582     case TLS_MODEL_LOCAL_EXEC:
03583       dest = gen_tlsmoff (addr, gen_rtx_REG (Pmode, 29));
03584       break;
03585     case TLS_MODEL_GLOBAL_DYNAMIC:
03586       {
03587   rtx retval;
03588 
03589   if (TARGET_INLINE_PLT)
03590     retval = gen_inlined_tls_plt (addr);
03591   else
03592     {
03593       /* call #gettlsoff(x) */
03594       retval = gen_reg_rtx (Pmode);
03595       emit_insn (gen_call_gettlsoff (retval, addr, picreg));
03596     }
03597   dest = gen_rtx_PLUS (Pmode, retval, tp);
03598   break;
03599       }
03600     default:
03601       abort ();
03602     }
03603 
03604   return dest;
03605 }
03606 
03607 rtx
03608 frv_legitimize_address (rtx x,
03609       rtx oldx ATTRIBUTE_UNUSED,
03610       enum machine_mode mode ATTRIBUTE_UNUSED)
03611 {
03612   if (GET_CODE (x) == SYMBOL_REF)
03613     {
03614       enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
03615       if (model != 0)
03616         return frv_legitimize_tls_address (x, model);
03617     }
03618 
03619   return NULL_RTX;
03620 }
03621 
03622 /* Test whether a local function descriptor is canonical, i.e.,
03623    whether we can use FUNCDESC_GOTOFF to compute the address of the
03624    function.  */
03625 
03626 static bool
03627 frv_local_funcdesc_p (rtx fnx)
03628 {
03629   tree fn;
03630   enum symbol_visibility vis;
03631   bool ret;
03632 
03633   if (! SYMBOL_REF_LOCAL_P (fnx))
03634     return FALSE;
03635 
03636   fn = SYMBOL_REF_DECL (fnx);
03637 
03638   if (! fn)
03639     return FALSE;
03640 
03641   vis = DECL_VISIBILITY (fn);
03642 
03643   if (vis == VISIBILITY_PROTECTED)
03644     /* Private function descriptors for protected functions are not
03645        canonical.  Temporarily change the visibility to global.  */
03646     vis = VISIBILITY_DEFAULT;
03647   else if (flag_shlib)
03648     /* If we're already compiling for a shared library (that, unlike
03649        executables, can't assume that the existence of a definition
03650        implies local binding), we can skip the re-testing.  */
03651     return TRUE;
03652 
03653   ret = default_binds_local_p_1 (fn, flag_pic);
03654 
03655   DECL_VISIBILITY (fn) = vis;
03656 
03657   return ret;
03658 }
03659 
03660 /* Load the _gp symbol into DEST.  SRC is supposed to be the FDPIC
03661    register.  */
03662 
03663 rtx
03664 frv_gen_GPsym2reg (rtx dest, rtx src)
03665 {
03666   tree gp = get_identifier ("_gp");
03667   rtx gp_sym = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (gp));
03668 
03669   return gen_symGOT2reg (dest, gp_sym, src, GEN_INT (R_FRV_GOT12));
03670 }
03671 
03672 static const char *
03673 unspec_got_name (int i)
03674 {
03675   switch (i)
03676     {
03677     case R_FRV_GOT12: return "got12";
03678     case R_FRV_GOTHI: return "gothi";
03679     case R_FRV_GOTLO: return "gotlo";
03680     case R_FRV_FUNCDESC: return "funcdesc";
03681     case R_FRV_FUNCDESC_GOT12: return "gotfuncdesc12";
03682     case R_FRV_FUNCDESC_GOTHI: return "gotfuncdeschi";
03683     case R_FRV_FUNCDESC_GOTLO: return "gotfuncdesclo";
03684     case R_FRV_FUNCDESC_VALUE: return "funcdescvalue";
03685     case R_FRV_FUNCDESC_GOTOFF12: return "gotofffuncdesc12";
03686     case R_FRV_FUNCDESC_GOTOFFHI: return "gotofffuncdeschi";
03687     case R_FRV_FUNCDESC_GOTOFFLO: return "gotofffuncdesclo";
03688     case R_FRV_GOTOFF12: return "gotoff12";
03689     case R_FRV_GOTOFFHI: return "gotoffhi";
03690     case R_FRV_GOTOFFLO: return "gotofflo";
03691     case R_FRV_GPREL12: return "gprel12";
03692     case R_FRV_GPRELHI: return "gprelhi";
03693     case R_FRV_GPRELLO: return "gprello";
03694     case R_FRV_GOTTLSOFF_HI: return "gottlsoffhi";
03695     case R_FRV_GOTTLSOFF_LO: return "gottlsofflo";
03696     case R_FRV_TLSMOFFHI: return "tlsmoffhi";
03697     case R_FRV_TLSMOFFLO: return "tlsmofflo";
03698     case R_FRV_TLSMOFF12: return "tlsmoff12";
03699     case R_FRV_TLSDESCHI: return "tlsdeschi";
03700     case R_FRV_TLSDESCLO: return "tlsdesclo";
03701     case R_FRV_GOTTLSDESCHI: return "gottlsdeschi";
03702     case R_FRV_GOTTLSDESCLO: return "gottlsdesclo";
03703     default: abort ();
03704     }
03705 }
03706 
03707 /* Write the assembler syntax for UNSPEC to STREAM.  Note that any offset
03708    is added inside the relocation operator.  */
03709 
03710 static void
03711 frv_output_const_unspec (FILE *stream, const struct frv_unspec *unspec)
03712 {
03713   fprintf (stream, "#%s(", unspec_got_name (unspec->reloc));
03714   output_addr_const (stream, plus_constant (unspec->symbol, unspec->offset));
03715   fputs (")", stream);
03716 }
03717 
03718 /* Implement FIND_BASE_TERM.  See whether ORIG_X represents #gprel12(foo)
03719    or #gotoff12(foo) for some small data symbol foo.  If so, return foo,
03720    otherwise return ORIG_X.  */
03721 
03722 rtx
03723 frv_find_base_term (rtx x)
03724 {
03725   struct frv_unspec unspec;
03726 
03727   if (frv_const_unspec_p (x, &unspec)
03728       && frv_small_data_reloc_p (unspec.symbol, unspec.reloc))
03729     return plus_constant (unspec.symbol, unspec.offset);
03730 
03731   return x;
03732 }
03733 
03734 /* Return 1 if operand is a valid FRV address.  CONDEXEC_P is true if
03735    the operand is used by a predicated instruction.  */
03736 
03737 static int
03738 frv_legitimate_memory_operand (rtx op, enum machine_mode mode, int condexec_p)
03739 {
03740   return ((GET_MODE (op) == mode || mode == VOIDmode)
03741     && GET_CODE (op) == MEM
03742     && frv_legitimate_address_p (mode, XEXP (op, 0),
03743                reload_completed, condexec_p, FALSE));
03744 }
03745 
03746 void
03747 frv_expand_fdpic_call (rtx *operands, bool ret_value, bool sibcall)
03748 {
03749   rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
03750   rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REG);
03751   rtx c, rvrtx=0;
03752   rtx addr;
03753 
03754   if (ret_value)
03755     {
03756       rvrtx = operands[0];
03757       operands ++;
03758     }
03759 
03760   addr = XEXP (operands[0], 0);
03761 
03762   /* Inline PLTs if we're optimizing for speed.  We'd like to inline
03763      any calls that would involve a PLT, but can't tell, since we
03764      don't know whether an extern function is going to be provided by
03765      a separate translation unit or imported from a separate module.
03766      When compiling for shared libraries, if the function has default
03767      visibility, we assume it's overridable, so we inline the PLT, but
03768      for executables, we don't really have a way to make a good
03769      decision: a function is as likely to be imported from a shared
03770      library as it is to be defined in the executable itself.  We
03771      assume executables will get global functions defined locally,
03772      whereas shared libraries will have them potentially overridden,
03773      so we only inline PLTs when compiling for shared libraries.
03774 
03775      In order to mark a function as local to a shared library, any
03776      non-default visibility attribute suffices.  Unfortunately,
03777      there's no simple way to tag a function declaration as ``in a
03778      different module'', which we could then use to trigger PLT
03779      inlining on executables.  There's -minline-plt, but it affects
03780      all external functions, so one would have to also mark function
03781      declarations available in the same module with non-default
03782      visibility, which is advantageous in itself.  */
03783   if (GET_CODE (addr) == SYMBOL_REF
03784       && ((!SYMBOL_REF_LOCAL_P (addr) && TARGET_INLINE_PLT)
03785     || sibcall))
03786     {
03787       rtx x, dest;
03788       dest = gen_reg_rtx (SImode);
03789       if (flag_pic != 1)
03790   x = gen_symGOTOFF2reg_hilo (dest, addr, OUR_FDPIC_REG,
03791             GEN_INT (R_FRV_FUNCDESC_GOTOFF12));
03792       else
03793   x = gen_symGOTOFF2reg (dest, addr, OUR_FDPIC_REG,
03794              GEN_INT (R_FRV_FUNCDESC_GOTOFF12));
03795       emit_insn (x);
03796       cfun->uses_pic_offset_table = TRUE;
03797       addr = dest;
03798     }    
03799   else if (GET_CODE (addr) == SYMBOL_REF)
03800     {
03801       /* These are always either local, or handled through a local
03802    PLT.  */
03803       if (ret_value)
03804   c = gen_call_value_fdpicsi (rvrtx, addr, operands[1],
03805             operands[2], picreg, lr);
03806       else
03807   c = gen_call_fdpicsi (addr, operands[1], operands[2], picreg, lr);
03808       emit_call_insn (c);
03809       return;
03810     }
03811   else if (! ldd_address_operand (addr, Pmode))
03812     addr = force_reg (Pmode, addr);
03813 
03814   picreg = gen_reg_rtx (DImode);
03815   emit_insn (gen_movdi_ldd (picreg, addr));
03816 
03817   if (sibcall && ret_value)
03818     c = gen_sibcall_value_fdpicdi (rvrtx, picreg, const0_rtx);
03819   else if (sibcall)
03820     c = gen_sibcall_fdpicdi (picreg, const0_rtx);
03821   else if (ret_value)
03822     c = gen_call_value_fdpicdi (rvrtx, picreg, const0_rtx, lr);
03823   else
03824     c = gen_call_fdpicdi (picreg, const0_rtx, lr);
03825   emit_call_insn (c);
03826 }
03827 
03828 /* An address operand that may use a pair of registers, an addressing
03829    mode that we reject in general.  */
03830 
03831 int
03832 ldd_address_operand (rtx x, enum machine_mode mode)
03833 {
03834   if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)
03835     return FALSE;
03836 
03837   return frv_legitimate_address_p (DImode, x, reload_completed, FALSE, TRUE);
03838 }
03839 
03840 int
03841 fdpic_fptr_operand (rtx op, enum machine_mode mode)
03842 {
03843   if (GET_MODE (op) != mode && mode != VOIDmode)
03844     return FALSE;
03845   if (GET_CODE (op) != REG)
03846     return FALSE;
03847   if (REGNO (op) != FDPIC_FPTR_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
03848     return FALSE;
03849   return TRUE;
03850 }
03851 
03852 /* Return 1 is OP is a memory operand, or will be turned into one by
03853    reload.  */
03854 
03855 int
03856 frv_load_operand (rtx op, enum machine_mode mode)
03857 {
03858   if (GET_MODE (op) != mode && mode != VOIDmode)
03859     return FALSE;
03860 
03861   if (reload_in_progress)
03862     {
03863       rtx tmp = op;
03864       if (GET_CODE (tmp) == SUBREG)
03865   tmp = SUBREG_REG (tmp);
03866       if (GET_CODE (tmp) == REG
03867     && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
03868   op = reg_equiv_memory_loc[REGNO (tmp)];
03869     }
03870 
03871   return op && memory_operand (op, mode);
03872 }
03873 
03874 
03875 /* Return 1 if operand is a GPR register or a FPR register.  */
03876 
03877 int
03878 gpr_or_fpr_operand (rtx op, enum machine_mode mode)
03879 {
03880   int regno;
03881 
03882   if (GET_MODE (op) != mode && mode != VOIDmode)
03883     return FALSE;
03884 
03885   if (GET_CODE (op) == SUBREG)
03886     {
03887       if (GET_CODE (SUBREG_REG (op)) != REG)
03888   return register_operand (op, mode);
03889 
03890       op = SUBREG_REG (op);
03891     }
03892 
03893   if (GET_CODE (op) != REG)
03894     return FALSE;
03895 
03896   regno = REGNO (op);
03897   if (GPR_P (regno) || FPR_P (regno) || regno >= FIRST_PSEUDO_REGISTER)
03898     return TRUE;
03899 
03900   return FALSE;
03901 }
03902 
03903 /* Return 1 if operand is a GPR register or 12 bit signed immediate.  */
03904 
03905 int
03906 gpr_or_int12_operand (rtx op, enum machine_mode mode)
03907 {
03908   if (GET_CODE (op) == CONST_INT)
03909     return IN_RANGE_P (INTVAL (op), -2048, 2047);
03910 
03911   if (got12_operand (op, mode))
03912     return true;
03913 
03914   if (GET_MODE (op) != mode && mode != VOIDmode)
03915     return FALSE;
03916 
03917   if (GET_CODE (op) == SUBREG)
03918     {
03919       if (GET_CODE (SUBREG_REG (op)) != REG)
03920   return register_operand (op, mode);
03921 
03922       op = SUBREG_REG (op);
03923     }
03924 
03925   if (GET_CODE (op) != REG)
03926     return FALSE;
03927 
03928   return GPR_OR_PSEUDO_P (REGNO (op));
03929 }
03930 
03931 /* Return 1 if operand is a GPR register, or a FPR register, or a 12 bit
03932    signed immediate.  */
03933 
03934 int
03935 gpr_fpr_or_int12_operand (rtx op, enum machine_mode mode)
03936 {
03937   int regno;
03938 
03939   if (GET_CODE (op) == CONST_INT)
03940     return IN_RANGE_P (INTVAL (op), -2048, 2047);
03941 
03942   if (GET_MODE (op) != mode && mode != VOIDmode)
03943     return FALSE;
03944 
03945   if (GET_CODE (op) == SUBREG)
03946     {
03947       if (GET_CODE (SUBREG_REG (op)) != REG)
03948   return register_operand (op, mode);
03949 
03950       op = SUBREG_REG (op);
03951     }
03952 
03953   if (GET_CODE (op) != REG)
03954     return FALSE;
03955 
03956   regno = REGNO (op);
03957   if (GPR_P (regno) || FPR_P (regno) || regno >= FIRST_PSEUDO_REGISTER)
03958     return TRUE;
03959 
03960   return FALSE;
03961 }
03962 
03963 /* Return 1 if operand is a register or 6 bit signed immediate.  */
03964 
03965 int
03966 fpr_or_int6_operand (rtx op, enum machine_mode mode)
03967 {
03968   if (GET_CODE (op) == CONST_INT)
03969     return IN_RANGE_P (INTVAL (op), -32, 31);
03970 
03971   if (GET_MODE (op) != mode && mode != VOIDmode)
03972     return FALSE;
03973 
03974   if (GET_CODE (op) == SUBREG)
03975     {
03976       if (GET_CODE (SUBREG_REG (op)) != REG)
03977   return register_operand (op, mode);
03978 
03979       op = SUBREG_REG (op);
03980     }
03981 
03982   if (GET_CODE (op) != REG)
03983     return FALSE;
03984 
03985   return FPR_OR_PSEUDO_P (REGNO (op));
03986 }
03987 
03988 /* Return 1 if operand is a register or 10 bit signed immediate.  */
03989 
03990 int
03991 gpr_or_int10_operand (rtx op, enum machine_mode mode)
03992 {
03993   if (GET_CODE (op) == CONST_INT)
03994     return IN_RANGE_P (INTVAL (op), -512, 511);
03995 
03996   if (GET_MODE (op) != mode && mode != VOIDmode)
03997     return FALSE;
03998 
03999   if (GET_CODE (op) == SUBREG)
04000     {
04001       if (GET_CODE (SUBREG_REG (op)) != REG)
04002   return register_operand (op, mode);
04003 
04004       op = SUBREG_REG (op);
04005     }
04006 
04007   if (GET_CODE (op) != REG)
04008     return FALSE;
04009 
04010   return GPR_OR_PSEUDO_P (REGNO (op));
04011 }
04012 
04013 /* Return 1 if operand is a register or an integer immediate.  */
04014 
04015 int
04016 gpr_or_int_operand (rtx op, enum machine_mode mode)
04017 {
04018   if (GET_CODE (op) == CONST_INT)
04019     return TRUE;
04020 
04021   if (GET_MODE (op) != mode && mode != VOIDmode)
04022     return FALSE;
04023 
04024   if (GET_CODE (op) == SUBREG)
04025     {
04026       if (GET_CODE (SUBREG_REG (op)) != REG)
04027   return register_operand (op, mode);
04028 
04029       op = SUBREG_REG (op);
04030     }
04031 
04032   if (GET_CODE (op) != REG)
04033     return FALSE;
04034 
04035   return GPR_OR_PSEUDO_P (REGNO (op));
04036 }
04037 
04038 /* Return 1 if operand is a 12 bit signed immediate.  */
04039 
04040 int
04041 int12_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04042 {
04043   if (GET_CODE (op) != CONST_INT)
04044     return FALSE;
04045 
04046   return IN_RANGE_P (INTVAL (op), -2048, 2047);
04047 }
04048 
04049 /* Return 1 if operand is a 6 bit signed immediate.  */
04050 
04051 int
04052 int6_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04053 {
04054   if (GET_CODE (op) != CONST_INT)
04055     return FALSE;
04056 
04057   return IN_RANGE_P (INTVAL (op), -32, 31);
04058 }
04059 
04060 /* Return 1 if operand is a 5 bit signed immediate.  */
04061 
04062 int
04063 int5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04064 {
04065   return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), -16, 15);
04066 }
04067 
04068 /* Return 1 if operand is a 5 bit unsigned immediate.  */
04069 
04070 int
04071 uint5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04072 {
04073   return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 31);
04074 }
04075 
04076 /* Return 1 if operand is a 4 bit unsigned immediate.  */
04077 
04078 int
04079 uint4_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04080 {
04081   return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 15);
04082 }
04083 
04084 /* Return 1 if operand is a 1 bit unsigned immediate (0 or 1).  */
04085 
04086 int
04087 uint1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04088 {
04089   return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 1);
04090 }
04091 
04092 /* Return 1 if operand is an integer constant that takes 2 instructions
04093    to load up and can be split into sethi/setlo instructions..  */
04094 
04095 int
04096 int_2word_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04097 {
04098   HOST_WIDE_INT value;
04099   REAL_VALUE_TYPE rv;
04100   long l;
04101 
04102   switch (GET_CODE (op))
04103     {
04104     default:
04105       break;
04106 
04107     case LABEL_REF:
04108       if (TARGET_FDPIC)
04109   return FALSE;
04110       
04111       return (flag_pic == 0);
04112 
04113     case CONST:
04114       if (flag_pic || TARGET_FDPIC)
04115   return FALSE;
04116 
04117       op = XEXP (op, 0);
04118       if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
04119   op = XEXP (op, 0);
04120       return GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF;
04121 
04122     case SYMBOL_REF:
04123       if (TARGET_FDPIC)
04124   return FALSE;
04125       
04126       /* small data references are already 1 word */
04127       return (flag_pic == 0) && (! SYMBOL_REF_SMALL_P (op));
04128 
04129     case CONST_INT:
04130       return ! IN_RANGE_P (INTVAL (op), -32768, 32767);
04131 
04132     case CONST_DOUBLE:
04133       if (GET_MODE (op) == SFmode)
04134   {
04135     REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
04136     REAL_VALUE_TO_TARGET_SINGLE (rv, l);
04137     value = l;
04138     return ! IN_RANGE_P (value, -32768, 32767);
04139   }
04140       else if (GET_MODE (op) == VOIDmode)
04141   {
04142     value = CONST_DOUBLE_LOW (op);
04143     return ! IN_RANGE_P (value, -32768, 32767);
04144   }
04145       break;
04146     }
04147 
04148   return FALSE;
04149 }
04150 
04151 /* Return 1 if operand is a 16 bit unsigned immediate.  */
04152 
04153 int
04154 uint16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04155 {
04156   if (GET_CODE (op) != CONST_INT)
04157     return FALSE;
04158 
04159   return IN_RANGE_P (INTVAL (op), 0, 0xffff);
04160 }
04161 
04162 /* Return 1 if operand is an integer constant with the bottom 16 bits
04163    clear.  */
04164 
04165 int
04166 upper_int16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04167 {
04168   if (GET_CODE (op) != CONST_INT)
04169     return FALSE;
04170 
04171   return ((INTVAL (op) & 0xffff) == 0);
04172 }
04173 
04174 /* Return true if operand is a GPR register.  */
04175 
04176 int
04177 integer_register_operand (rtx op, enum machine_mode mode)
04178 {
04179   if (GET_MODE (op) != mode && mode != VOIDmode)
04180     return FALSE;
04181 
04182   if (GET_CODE (op) == SUBREG)
04183     {
04184       if (GET_CODE (SUBREG_REG (op)) != REG)
04185   return register_operand (op, mode);
04186 
04187       op = SUBREG_REG (op);
04188     }
04189 
04190   if (GET_CODE (op) != REG)
04191     return FALSE;
04192 
04193   return GPR_OR_PSEUDO_P (REGNO (op));
04194 }
04195 
04196 /* Return true if operand is a GPR register.  Do not allow SUBREG's
04197    here, in order to prevent a combine bug.  */
04198 
04199 int
04200 gpr_no_subreg_operand (rtx op, enum machine_mode mode)
04201 {
04202   if (GET_MODE (op) != mode && mode != VOIDmode)
04203     return FALSE;
04204 
04205   if (GET_CODE (op) != REG)
04206     return FALSE;
04207 
04208   return GPR_OR_PSEUDO_P (REGNO (op));
04209 }
04210 
04211 /* Return true if operand is a FPR register.  */
04212 
04213 int
04214 fpr_operand (rtx op, enum machine_mode mode)
04215 {
04216   if (GET_MODE (op) != mode && mode != VOIDmode)
04217     return FALSE;
04218 
04219   if (GET_CODE (op) == SUBREG)
04220     {
04221       if (GET_CODE (SUBREG_REG (op)) != REG)
04222         return register_operand (op, mode);
04223 
04224       op = SUBREG_REG (op);
04225     }
04226 
04227   if (GET_CODE (op) != REG)
04228     return FALSE;
04229 
04230   return FPR_OR_PSEUDO_P (REGNO (op));
04231 }
04232 
04233 /* Return true if operand is an even GPR or FPR register.  */
04234 
04235 int
04236 even_reg_operand (rtx op, enum machine_mode mode)
04237 {
04238   int regno;
04239 
04240   if (GET_MODE (op) != mode && mode != VOIDmode)
04241     return FALSE;
04242 
04243   if (GET_CODE (op) == SUBREG)
04244     {
04245       if (GET_CODE (SUBREG_REG (op)) != REG)
04246         return register_operand (op, mode);
04247 
04248       op = SUBREG_REG (op);
04249     }
04250 
04251   if (GET_CODE (op) != REG)
04252     return FALSE;
04253 
04254   regno = REGNO (op);
04255   if (regno >= FIRST_PSEUDO_REGISTER)
04256     return TRUE;
04257 
04258   if (GPR_P (regno))
04259     return (((regno - GPR_FIRST) & 1) == 0);
04260 
04261   if (FPR_P (regno))
04262     return (((regno - FPR_FIRST) & 1) == 0);
04263 
04264   return FALSE;
04265 }
04266 
04267 /* Return true if operand is an odd GPR register.  */
04268 
04269 int
04270 odd_reg_operand (rtx op, enum machine_mode mode)
04271 {
04272   int regno;
04273 
04274   if (GET_MODE (op) != mode && mode != VOIDmode)
04275     return FALSE;
04276 
04277   if (GET_CODE (op) == SUBREG)
04278     {
04279       if (GET_CODE (SUBREG_REG (op)) != REG)
04280         return register_operand (op, mode);
04281 
04282       op = SUBREG_REG (op);
04283     }
04284 
04285   if (GET_CODE (op) != REG)
04286     return FALSE;
04287 
04288   regno = REGNO (op);
04289   /* Assume that reload will give us an even register.  */
04290   if (regno >= FIRST_PSEUDO_REGISTER)
04291     return FALSE;
04292 
04293   if (GPR_P (regno))
04294     return (((regno - GPR_FIRST) & 1) != 0);
04295 
04296   if (FPR_P (regno))
04297     return (((regno - FPR_FIRST) & 1) != 0);
04298 
04299   return FALSE;
04300 }
04301 
04302 /* Return true if operand is an even GPR register.  */
04303 
04304 int
04305 even_gpr_operand (rtx op, enum machine_mode mode)
04306 {
04307   int regno;
04308 
04309   if (GET_MODE (op) != mode && mode != VOIDmode)
04310     return FALSE;
04311 
04312   if (GET_CODE (op) == SUBREG)
04313     {
04314       if (GET_CODE (SUBREG_REG (op)) != REG)
04315         return register_operand (op, mode);
04316 
04317       op = SUBREG_REG (op);
04318     }
04319 
04320   if (GET_CODE (op) != REG)
04321     return FALSE;
04322 
04323   regno = REGNO (op);
04324   if (regno >= FIRST_PSEUDO_REGISTER)
04325     return TRUE;
04326 
04327   if (! GPR_P (regno))
04328     return FALSE;
04329 
04330   return (((regno - GPR_FIRST) & 1) == 0);
04331 }
04332 
04333 /* Return true if operand is an odd GPR register.  */
04334 
04335 int
04336 odd_gpr_operand (rtx op, enum machine_mode mode)
04337 {
04338   int regno;
04339 
04340   if (GET_MODE (op) != mode && mode != VOIDmode)
04341     return FALSE;
04342 
04343   if (GET_CODE (op) == SUBREG)
04344     {
04345       if (GET_CODE (SUBREG_REG (op)) != REG)
04346         return register_operand (op, mode);
04347 
04348       op = SUBREG_REG (op);
04349     }
04350 
04351   if (GET_CODE (op) != REG)
04352     return FALSE;
04353 
04354   regno = REGNO (op);
04355   /* Assume that reload will give us an even register.  */
04356   if (regno >= FIRST_PSEUDO_REGISTER)
04357     return FALSE;
04358 
04359   if (! GPR_P (regno))
04360     return FALSE;
04361 
04362   return (((regno - GPR_FIRST) & 1) != 0);
04363 }
04364 
04365 /* Return true if operand is a quad aligned FPR register.  */
04366 
04367 int
04368 quad_fpr_operand (rtx op, enum machine_mode mode)
04369 {
04370   int regno;
04371 
04372   if (GET_MODE (op) != mode && mode != VOIDmode)
04373     return FALSE;
04374 
04375   if (GET_CODE (op) == SUBREG)
04376     {
04377       if (GET_CODE (SUBREG_REG (op)) != REG)
04378         return register_operand (op, mode);
04379 
04380       op = SUBREG_REG (op);
04381     }
04382 
04383   if (GET_CODE (op) != REG)
04384     return FALSE;
04385 
04386   regno = REGNO (op);
04387   if (regno >= FIRST_PSEUDO_REGISTER)
04388     return TRUE;
04389 
04390   if (! FPR_P (regno))
04391     return FALSE;
04392 
04393   return (((regno - FPR_FIRST) & 3) == 0);
04394 }
04395 
04396 /* Return true if operand is an even FPR register.  */
04397 
04398 int
04399 even_fpr_operand (rtx op, enum machine_mode mode)
04400 {
04401   int regno;
04402 
04403   if (GET_MODE (op) != mode && mode != VOIDmode)
04404     return FALSE;
04405 
04406   if (GET_CODE (op) == SUBREG)
04407     {
04408       if (GET_CODE (SUBREG_REG (op)) != REG)
04409         return register_operand (op, mode);
04410 
04411       op = SUBREG_REG (op);
04412     }
04413 
04414   if (GET_CODE (op) != REG)
04415     return FALSE;
04416 
04417   regno = REGNO (op);
04418   if (regno >= FIRST_PSEUDO_REGISTER)
04419     return TRUE;
04420 
04421   if (! FPR_P (regno))
04422     return FALSE;
04423 
04424   return (((regno - FPR_FIRST) & 1) == 0);
04425 }
04426 
04427 /* Return true if operand is an odd FPR register.  */
04428 
04429 int
04430 odd_fpr_operand (rtx op, enum machine_mode mode)
04431 {
04432   int regno;
04433 
04434   if (GET_MODE (op) != mode && mode != VOIDmode)
04435     return FALSE;
04436 
04437   if (GET_CODE (op) == SUBREG)
04438     {
04439       if (GET_CODE (SUBREG_REG (op)) != REG)
04440         return register_operand (op, mode);
04441 
04442       op = SUBREG_REG (op);
04443     }
04444 
04445   if (GET_CODE (op) != REG)
04446     return FALSE;
04447 
04448   regno = REGNO (op);
04449   /* Assume that reload will give us an even register.  */
04450   if (regno >= FIRST_PSEUDO_REGISTER)
04451     return FALSE;
04452 
04453   if (! FPR_P (regno))
04454     return FALSE;
04455 
04456   return (((regno - FPR_FIRST) & 1) != 0);
04457 }
04458 
04459 /* Return true if operand is a 2 word memory address that can be loaded in one
04460    instruction to load or store.  We assume the stack and frame pointers are
04461    suitably aligned, and variables in the small data area.  FIXME -- at some we
04462    should recognize other globals and statics. We can't assume that any old
04463    pointer is aligned, given that arguments could be passed on an odd word on
04464    the stack and the address taken and passed through to another function.  */
04465 
04466 int
04467 dbl_memory_one_insn_operand (rtx op, enum machine_mode mode)
04468 {
04469   rtx addr;
04470   rtx addr_reg;
04471 
04472   if (! TARGET_DWORD)
04473     return FALSE;
04474 
04475   if (GET_CODE (op) != MEM)
04476     return FALSE;
04477 
04478   if (mode != VOIDmode && GET_MODE_SIZE (mode) != 2*UNITS_PER_WORD)
04479     return FALSE;
04480 
04481   addr = XEXP (op, 0);
04482   if (GET_CODE (addr) == REG)
04483     addr_reg = addr;
04484 
04485   else if (GET_CODE (addr) == PLUS)
04486     {
04487       rtx addr0 = XEXP (addr, 0);
04488       rtx addr1 = XEXP (addr, 1);
04489 
04490       if (GET_CODE (addr0) != REG)
04491   return FALSE;
04492 
04493       if (got12_operand (addr1, VOIDmode))
04494   return TRUE;
04495 
04496       if (GET_CODE (addr1) != CONST_INT)
04497   return FALSE;
04498 
04499       if ((INTVAL (addr1) & 7) != 0)
04500   return FALSE;
04501 
04502       addr_reg = addr0;
04503     }
04504 
04505   else
04506     return FALSE;
04507 
04508   if (addr_reg == frame_pointer_rtx || addr_reg == stack_pointer_rtx)
04509     return TRUE;
04510 
04511   return FALSE;
04512 }
04513 
04514 /* Return true if operand is a 2 word memory address that needs to
04515    use two instructions to load or store.  */
04516 
04517 int
04518 dbl_memory_two_insn_operand (rtx op, enum machine_mode mode)
04519 {
04520   if (GET_CODE (op) != MEM)
04521     return FALSE;
04522 
04523   if (mode != VOIDmode && GET_MODE_SIZE (mode) != 2*UNITS_PER_WORD)
04524     return FALSE;
04525 
04526   if (! TARGET_DWORD)
04527     return TRUE;
04528 
04529   return ! dbl_memory_one_insn_operand (op, mode);
04530 }
04531 
04532 /* Return true if operand is something that can be an output for a move
04533    operation.  */
04534 
04535 int
04536 move_destination_operand (rtx op, enum machine_mode mode)
04537 {
04538   rtx subreg;
04539   enum rtx_code code;
04540 
04541   switch (GET_CODE (op))
04542     {
04543     default:
04544       break;
04545 
04546     case SUBREG:
04547       if (GET_MODE (op) != mode && mode != VOIDmode)
04548         return FALSE;
04549 
04550       subreg = SUBREG_REG (op);
04551       code = GET_CODE (subreg);
04552       if (code == MEM)
04553   return frv_legitimate_address_p (mode, XEXP (subreg, 0),
04554            reload_completed, FALSE, FALSE);
04555 
04556       return (code == REG);
04557 
04558     case REG:
04559       if (GET_MODE (op) != mode && mode != VOIDmode)
04560         return FALSE;
04561 
04562       return TRUE;
04563 
04564     case MEM:
04565       return frv_legitimate_memory_operand (op, mode, FALSE);
04566     }
04567 
04568   return FALSE;
04569 }
04570 
04571 /* Return true if we the operand is a valid destination for a movcc_fp
04572    instruction.  This means rejecting fcc_operands, since we need
04573    scratch registers to write to them.  */
04574 
04575 int
04576 movcc_fp_destination_operand (rtx op, enum machine_mode mode)
04577 {
04578   if (fcc_operand (op, mode))
04579     return FALSE;
04580 
04581   return move_destination_operand (op, mode);
04582 }
04583 
04584 /* Look for a SYMBOL_REF of a function in an rtx.  We always want to
04585    process these separately from any offsets, such that we add any
04586    offsets to the function descriptor (the actual pointer), not to the
04587    function address.  */
04588 
04589 static bool
04590 frv_function_symbol_referenced_p (rtx x)
04591 {
04592   const char *format;
04593   int length;
04594   int j;
04595 
04596   if (GET_CODE (x) == SYMBOL_REF)
04597     return SYMBOL_REF_FUNCTION_P (x);
04598 
04599   length = GET_RTX_LENGTH (GET_CODE (x));
04600   format = GET_RTX_FORMAT (GET_CODE (x));
04601 
04602   for (j = 0; j < length; ++j)
04603     {
04604       switch (format[j])
04605   {
04606   case 'e':
04607     if (frv_function_symbol_referenced_p (XEXP (x, j)))
04608       return TRUE;
04609     break;
04610 
04611   case 'V':
04612   case 'E':
04613     if (XVEC (x, j) != 0)
04614       {
04615         int k;
04616         for (k = 0; k < XVECLEN (x, j); ++k)
04617     if (frv_function_symbol_referenced_p (XVECEXP (x, j, k)))
04618       return TRUE;
04619       }
04620     break;
04621 
04622   default:
04623     /* Nothing to do.  */
04624     break;
04625   }
04626     }
04627 
04628   return FALSE;
04629 }
04630 
04631 /* Return true if operand is something that can be an input for a move
04632    operation.  */
04633 
04634 int
04635 move_source_operand (rtx op, enum machine_mode mode)
04636 {
04637   rtx subreg;
04638   enum rtx_code code;
04639 
04640   switch (GET_CODE (op))
04641     {
04642     default:
04643       break;
04644 
04645     case CONST_INT:
04646     case CONST_DOUBLE:
04647       return immediate_operand (op, mode);
04648 
04649     case SUBREG:
04650       if (GET_MODE (op) != mode && mode != VOIDmode)
04651         return FALSE;
04652 
04653       subreg = SUBREG_REG (op);
04654       code = GET_CODE (subreg);
04655       if (code == MEM)
04656   return frv_legitimate_address_p (mode, XEXP (subreg, 0),
04657            reload_completed, FALSE, FALSE);
04658 
04659       return (code == REG);
04660 
04661     case REG:
04662       if (GET_MODE (op) != mode && mode != VOIDmode)
04663         return FALSE;
04664 
04665       return TRUE;
04666 
04667     case MEM:
04668       return frv_legitimate_memory_operand (op, mode, FALSE);
04669     }
04670 
04671   return FALSE;
04672 }
04673 
04674 /* Return true if operand is something that can be an output for a conditional
04675    move operation.  */
04676 
04677 int
04678 condexec_dest_operand (rtx op, enum machine_mode mode)
04679 {
04680   rtx subreg;
04681   enum rtx_code code;
04682 
04683   switch (GET_CODE (op))
04684     {
04685     default:
04686       break;
04687 
04688     case SUBREG:
04689       if (GET_MODE (op) != mode && mode != VOIDmode)
04690         return FALSE;
04691 
04692       subreg = SUBREG_REG (op);
04693       code = GET_CODE (subreg);
04694       if (code == MEM)
04695   return frv_legitimate_address_p (mode, XEXP (subreg, 0),
04696            reload_completed, TRUE, FALSE);
04697 
04698       return (code == REG);
04699 
04700     case REG:
04701       if (GET_MODE (op) != mode && mode != VOIDmode)
04702         return FALSE;
04703 
04704       return TRUE;
04705 
04706     case MEM:
04707       return frv_legitimate_memory_operand (op, mode, TRUE);
04708     }
04709 
04710   return FALSE;
04711 }
04712 
04713 /* Return true if operand is something that can be an input for a conditional
04714    move operation.  */
04715 
04716 int
04717 condexec_source_operand (rtx op, enum machine_mode mode)
04718 {
04719   rtx subreg;
04720   enum rtx_code code;
04721 
04722   switch (GET_CODE (op))
04723     {
04724     default:
04725       break;
04726 
04727     case CONST_INT:
04728     case CONST_DOUBLE:
04729       return ZERO_P (op);
04730 
04731     case SUBREG:
04732       if (GET_MODE (op) != mode && mode != VOIDmode)
04733         return FALSE;
04734 
04735       subreg = SUBREG_REG (op);
04736       code = GET_CODE (subreg);
04737       if (code == MEM)
04738   return frv_legitimate_address_p (mode, XEXP (subreg, 0),
04739            reload_completed, TRUE, FALSE);
04740 
04741       return (code == REG);
04742 
04743     case REG:
04744       if (GET_MODE (op) != mode && mode != VOIDmode)
04745         return FALSE;
04746 
04747       return TRUE;
04748 
04749     case MEM:
04750       return frv_legitimate_memory_operand (op, mode, TRUE);
04751     }
04752 
04753   return FALSE;
04754 }
04755 
04756 /* Return true if operand is a register of any flavor or a 0 of the
04757    appropriate type.  */
04758 
04759 int
04760 reg_or_0_operand (rtx op, enum machine_mode mode)
04761 {
04762   switch (GET_CODE (op))
04763     {
04764     default:
04765       break;
04766 
04767     case REG:
04768     case SUBREG:
04769       if (GET_MODE (op) != mode && mode != VOIDmode)
04770   return FALSE;
04771 
04772       return register_operand (op, mode);
04773 
04774     case CONST_INT:
04775     case CONST_DOUBLE:
04776       return ZERO_P (op);
04777     }
04778 
04779   return FALSE;
04780 }
04781 
04782 /* Return true if operand is the link register.  */
04783 
04784 int
04785 lr_operand (rtx op, enum machine_mode mode)
04786 {
04787   if (GET_CODE (op) != REG)
04788     return FALSE;
04789 
04790   if (GET_MODE (op) != mode && mode != VOIDmode)
04791     return FALSE;
04792 
04793   if (REGNO (op) != LR_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
04794     return FALSE;
04795 
04796   return TRUE;
04797 }
04798 
04799 /* Return true if operand is the uClinux PIC register.  */
04800 
04801 int
04802 fdpic_operand (rtx op, enum machine_mode mode)
04803 {
04804   if (!TARGET_FDPIC)
04805     return FALSE;
04806 
04807   if (GET_CODE (op) != REG)
04808     return FALSE;
04809 
04810   if (GET_MODE (op) != mode && mode != VOIDmode)
04811     return FALSE;
04812 
04813   if (REGNO (op) != FDPIC_REGNO && REGNO (op) < FIRST_PSEUDO_REGISTER)
04814     return FALSE;
04815 
04816   return TRUE;
04817 }
04818 
04819 int
04820 got12_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04821 {
04822   struct frv_unspec unspec;
04823 
04824   if (frv_const_unspec_p (op, &unspec))
04825     switch (unspec.reloc)
04826       {
04827       case R_FRV_GOT12:
04828       case R_FRV_GOTOFF12:
04829       case R_FRV_FUNCDESC_GOT12:
04830       case R_FRV_FUNCDESC_GOTOFF12:
04831       case R_FRV_GPREL12:
04832       case R_FRV_TLSMOFF12:
04833   return true;
04834       }
04835   return false;
04836 }
04837 
04838 /* Return true if OP is a valid const-unspec expression.  */
04839 
04840 int
04841 const_unspec_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
04842 {
04843   struct frv_unspec unspec;
04844 
04845   return frv_const_unspec_p (op, &unspec);
04846 }
04847 
04848 /* Return true if operand is a gpr register or a valid memory operand.  */
04849 
04850 int
04851 gpr_or_memory_operand (rtx op, enum machine_mode mode)
04852 {
04853   return (integer_register_operand (op, mode)
04854     || frv_legitimate_memory_operand (op, mode, FALSE));
04855 }
04856 
04857 /* Return true if operand is a gpr register, a valid memory operand,
04858    or a memory operand that can be made valid using an additional gpr
04859    register.  */
04860 
04861 int
04862 gpr_or_memory_operand_with_scratch (rtx op, enum machine_mode mode)
04863 {
04864   rtx addr;
04865 
04866   if (gpr_or_memory_operand (op, mode))
04867     return TRUE;
04868 
04869   if (GET_CODE (op) != MEM)
04870     return FALSE;
04871 
04872   if (GET_MODE (op) != mode)
04873     return FALSE;
04874 
04875   addr = XEXP (op, 0);
04876 
04877   if (GET_CODE (addr) != PLUS)
04878     return FALSE;
04879       
04880   if (!integer_register_operand (XEXP (addr, 0), Pmode))
04881     return FALSE;
04882 
04883   if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
04884     return FALSE;
04885 
04886   return TRUE;
04887 }
04888 
04889 /* Return true if operand is a fpr register or a valid memory operation.  */
04890 
04891 int
04892 fpr_or_memory_operand (rtx op, enum machine_mode mode)
04893 {
04894   return (fpr_operand (op, mode)
04895     || frv_legitimate_memory_operand (op, mode, FALSE));
04896 }
04897 
04898 /* Return true if operand is an icc register.  */
04899 
04900 int
04901 icc_operand (rtx op, enum machine_mode mode)
04902 {
04903   int regno;
04904 
04905   if (GET_MODE (op) != mode && mode != VOIDmode)
04906     return FALSE;
04907 
04908   if (GET_CODE (op) != REG)
04909     return FALSE;
04910 
04911   regno = REGNO (op);
04912   return ICC_OR_PSEUDO_P (regno);
04913 }
04914 
04915 /* Return true if operand is an fcc register.  */
04916 
04917 int
04918 fcc_operand (rtx op, enum machine_mode mode)
04919 {
04920   int regno;
04921 
04922   if (GET_MODE (op) != mode && mode != VOIDmode)
04923     return FALSE;
04924 
04925   if (GET_CODE (op) != REG)
04926     return FALSE;
04927 
04928   regno = REGNO (op);
04929   return FCC_OR_PSEUDO_P (regno);
04930 }
04931 
04932 /* Return true if operand is either an fcc or icc register.  */
04933 
04934 int
04935 cc_operand (rtx op, enum machine_mode mode)
04936 {
04937   int regno;
04938 
04939   if (GET_MODE (op) != mode && mode != VOIDmode)
04940     return FALSE;
04941 
04942   if (GET_CODE (op) != REG)
04943     return FALSE;
04944 
04945   regno = REGNO (op);
04946   if (CC_OR_PSEUDO_P (regno))
04947     return TRUE;
04948 
04949   return FALSE;
04950 }
04951 
04952 /* Return true if operand is an integer CCR register.  */
04953 
04954 int
04955 icr_operand (rtx op, enum machine_mode mode)
04956 {
04957   int regno;
04958 
04959   if (GET_MODE (op) != mode && mode != VOIDmode)
04960     return FALSE;
04961 
04962   if (GET_CODE (op) != REG)
04963     return FALSE;
04964 
04965   regno = REGNO (op);
04966   return ICR_OR_PSEUDO_P (regno);
04967 }
04968 
04969 /* Return true if operand is an fcc register.  */
04970 
04971 int
04972 fcr_operand (rtx op, enum machine_mode mode)
04973 {
04974   int regno;
04975 
04976   if (GET_MODE (op) != mode && mode != VOIDmode)
04977     return FALSE;
04978 
04979   if (GET_CODE (op) != REG)
04980     return FALSE;
04981 
04982   regno = REGNO (op);
04983   return FCR_OR_PSEUDO_P (regno);
04984 }
04985 
04986 /* Return true if operand is either an fcc or icc register.  */
04987 
04988 int
04989 cr_operand (rtx op, enum machine_mode mode)
04990 {
04991   int regno;
04992 
04993   if (GET_MODE (op) != mode && mode != VOIDmode)
04994     return FALSE;
04995 
04996   if (GET_CODE (op) != REG)
04997     return FALSE;
04998 
04999   regno = REGNO (op);
05000   if (CR_OR_PSEUDO_P (regno))
05001     return TRUE;
05002 
05003   return FALSE;
05004 }
05005 
05006 /* Return true if operand is a memory reference suitable for a call.  */
05007 
05008 int
05009 call_operand (rtx op, enum machine_mode mode)
05010 {
05011   if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
05012     return FALSE;
05013 
05014   if (GET_CODE (op) == SYMBOL_REF)
05015     return !TARGET_LONG_CALLS || SYMBOL_REF_LOCAL_P (op);
05016 
05017   /* Note this doesn't allow reg+reg or reg+imm12 addressing (which should
05018      never occur anyway), but prevents reload from not handling the case
05019      properly of a call through a pointer on a function that calls
05020      vfork/setjmp, etc. due to the need to flush all of the registers to stack.  */
05021   return gpr_or_int12_operand (op, mode);
05022 }
05023 
05024 /* Return true if operand is a memory reference suitable for a sibcall.  */
05025 
05026 int
05027 sibcall_operand (rtx op, enum machine_mode mode)
05028 {
05029   if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
05030     return FALSE;
05031 
05032   /* Note this doesn't allow reg+reg or reg+imm12 addressing (which should
05033      never occur anyway), but prevents reload from not handling the case
05034      properly of a call through a pointer on a function that calls
05035      vfork/setjmp, etc. due to the need to flush all of the registers to stack.  */
05036   return gpr_or_int12_operand (op, mode);
05037 }
05038 
05039 /* Returns 1 if OP is either a SYMBOL_REF or a constant.  */
05040 int
05041 symbolic_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
05042 {
05043   enum rtx_code c = GET_CODE (op);
05044 
05045   if (c == CONST)
05046     {
05047       /* Allow (const:SI (plus:SI (symbol_ref) (const_int))).  */
05048       return GET_MODE (op) == SImode
05049   && GET_CODE (XEXP (op, 0)) == PLUS
05050   && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
05051   && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT;
05052     }
05053 
05054   return c == SYMBOL_REF || c == CONST_INT;
05055 }
05056 
05057 /* Return true if operator is a kind of relational operator.  */
05058 
05059 int
05060 relational_operator (rtx op, enum machine_mode mode)
05061 {
05062   return (integer_relational_operator (op, mode)
05063     || float_relational_operator (op, mode));
05064 }
05065 
05066 /* Return true if OP is a relational operator suitable for CCmode,
05067    CC_UNSmode or CC_NZmode.  */
05068 
05069 int
05070 integer_relational_operator (rtx op, enum machine_mode mode)
05071 {
05072   if (mode != VOIDmode && mode != GET_MODE (op))
05073     return FALSE;
05074 
05075   /* The allowable relations depend on the mode of the ICC register.  */
05076   switch (GET_CODE (op))
05077     {
05078     default:
05079       return FALSE;
05080 
05081     case EQ:
05082     case NE:
05083     case LT:
05084     case GE:
05085       return (GET_MODE (XEXP (op, 0)) == CC_NZmode
05086         || GET_MODE (XEXP (op, 0)) == CCmode);
05087 
05088     case LE:
05089     case GT:
05090       return GET_MODE (XEXP (op, 0)) == CCmode;
05091 
05092     case GTU:
05093     case GEU:
05094     case LTU:
05095     case LEU:
05096       return (GET_MODE (XEXP (op, 0)) == CC_NZmode
05097         || GET_MODE (XEXP (op, 0)) == CC_UNSmode);
05098     }
05099 }
05100 
05101 /* Return true if operator is a floating point relational operator.  */
05102 
05103 int
05104 float_relational_operator (rtx op, enum machine_mode mode)
05105 {
05106   if (mode != VOIDmode && mode != GET_MODE (op))
05107     return FALSE;
05108 
05109   switch (GET_CODE (op))
05110     {
05111     default:
05112       return FALSE;
05113 
05114     case EQ: case NE:
05115     case LE: case LT:
05116     case GE: case GT:
05117 #if 0
05118     case UEQ: case UNE:
05119     case ULE: case ULT:
05120     case UGE: case UGT:
05121     case ORDERED:
05122     case UNORDERED:
05123 #endif
05124       return GET_MODE (XEXP (op, 0)) == CC_FPmode;
05125     }
05126 }
05127 
05128 /* Return true if operator is EQ/NE of a conditional execution register.  */
05129 
05130 int
05131 ccr_eqne_operator (rtx op, enum machine_mode mode)
05132 {
05133   enum machine_mode op_mode = GET_MODE (op);
05134   rtx op0;
05135   rtx op1;
05136   int regno;
05137 
05138   if (mode != VOIDmode && op_mode != mode)
05139     return FALSE;
05140 
05141   switch (GET_CODE (op))
05142     {
05143     default:
05144       return FALSE;
05145 
05146     case EQ:
05147     case NE:
05148       break;
05149     }
05150 
05151   op1 = XEXP (op, 1);
05152   if (op1 != const0_rtx)
05153     return FALSE;
05154 
05155   op0 = XEXP (op, 0);
05156   if (GET_CODE (op0) != REG)
05157     return FALSE;
05158 
05159   regno = REGNO (op0);
05160   if (op_mode == CC_CCRmode && CR_OR_PSEUDO_P (regno))
05161     return TRUE;
05162 
05163   return FALSE;
05164 }
05165 
05166 /* Return true if operator is a minimum or maximum operator (both signed and
05167    unsigned).  */
05168 
05169 int
05170 minmax_operator (rtx op, enum machine_mode mode)
05171 {
05172   if (mode != VOIDmode && mode != GET_MODE (op))
05173     return FALSE;
05174 
05175   switch (GET_CODE (op))
05176     {
05177     default:
05178       return FALSE;
05179 
05180     case SMIN:
05181     case SMAX:
05182     case UMIN:
05183     case UMAX:
05184       break;
05185     }
05186 
05187   if (! integer_register_operand (XEXP (op, 0), mode))
05188     return FALSE;
05189 
05190   if (! gpr_or_int10_operand (XEXP (op, 1), mode))
05191     return FALSE;
05192 
05193   return TRUE;
05194 }
05195 
05196 /* Return true if operator is an integer binary operator that can executed
05197    conditionally and takes 1 cycle.  */
05198 
05199 int
05200 condexec_si_binary_operator (rtx op, enum machine_mode mode)
05201 {
05202   enum machine_mode op_mode = GET_MODE (op);
05203 
05204   if (mode != VOIDmode && op_mode != mode)
05205     return FALSE;
05206 
05207   switch (GET_CODE (op))
05208     {
05209     default:
05210       return FALSE;
05211 
05212     case PLUS:
05213     case MINUS:
05214     case AND:
05215     case IOR:
05216     case XOR:
05217     case ASHIFT:
05218     case ASHIFTRT:
05219     case LSHIFTRT:
05220       return TRUE;
05221     }
05222 }
05223 
05224 /* Return true if operator is an integer binary operator that can be
05225    executed conditionally by a media instruction.  */
05226 
05227 int
05228 condexec_si_media_operator (rtx op, enum machine_mode mode)
05229 {
05230   enum machine_mode op_mode = GET_MODE (op);
05231 
05232   if (mode != VOIDmode && op_mode != mode)
05233     return FALSE;
05234 
05235   switch (GET_CODE (op))
05236     {
05237     default:
05238       return FALSE;
05239 
05240     case AND:
05241     case IOR:
05242     case XOR:
05243       return TRUE;
05244     }
05245 }
05246 
05247 /* Return true if operator is an integer division operator that can executed
05248    conditionally.  */
05249 
05250 int
05251 condexec_si_divide_operator (rtx op, enum machine_mode mode)
05252 {
05253   enum machine_mode op_mode = GET_MODE (op);
05254 
05255   if (mode != VOIDmode && op_mode != mode)
05256     return FALSE;
05257 
05258   switch (GET_CODE (op))
05259     {
05260     default:
05261       return FALSE;
05262 
05263     case DIV:
05264     case UDIV:
05265       return TRUE;
05266     }
05267 }
05268 
05269 /* Return true if operator is an integer unary operator that can executed
05270    conditionally.  */
05271 
05272 int
05273 condexec_si_unary_operator (rtx op, enum machine_mode mode)
05274 {
05275   enum machine_mode op_mode = GET_MODE (op);
05276 
05277   if (mode != VOIDmode && op_mode != mode)
05278     return FALSE;
05279 
05280   switch (GET_CODE (op))
05281     {
05282     default:
05283       return FALSE;
05284 
05285     case NEG:
05286     case NOT:
05287       return TRUE;
05288     }
05289 }
05290 
05291 /* Return true if operator is a conversion-type expression that can be
05292    evaluated conditionally by floating-point instructions.  */
05293 
05294 int
05295 condexec_sf_conv_operator (rtx op, enum machine_mode mode)
05296 {
05297   enum machine_mode op_mode = GET_MODE (op);
05298 
05299   if (mode != VOIDmode && op_mode != mode)
05300     return FALSE;
05301 
05302   switch (GET_CODE (op))
05303     {
05304     default:
05305       return FALSE;
05306 
05307     case NEG:
05308     case ABS:
05309       return TRUE;
05310     }
05311 }
05312 
05313 /* Return true if operator is an addition or subtraction expression.
05314    Such expressions can be evaluated conditionally by floating-point
05315    instructions.  */
05316 
05317 int
05318 condexec_sf_add_operator (rtx op, enum machine_mode mode)
05319 {
05320   enum machine_mode op_mode = GET_MODE (op);
05321 
05322   if (mode != VOIDmode && op_mode != mode)
05323     return FALSE;
05324 
05325   switch (GET_CODE (op))
05326     {
05327     default:
05328       return FALSE;
05329 
05330     case PLUS:
05331     case MINUS:
05332       return TRUE;
05333     }
05334 }
05335 
05336 /* Return true if the memory operand is one that can be conditionally
05337    executed.  */
05338 
05339 int
05340 condexec_memory_operand (rtx op, enum machine_mode mode)
05341 {
05342   enum machine_mode op_mode = GET_MODE (op);
05343   rtx addr;
05344 
05345   if (mode != VOIDmode && op_mode != mode)
05346     return FALSE;
05347 
05348   switch (op_mode)
05349     {
05350     default:
05351       return FALSE;
05352 
05353     case QImode:
05354     case HImode:
05355     case SImode:
05356     case SFmode:
05357       break;
05358     }
05359 
05360   if (GET_CODE (op) != MEM)
05361     return FALSE;
05362 
05363   addr = XEXP (op, 0);
05364   return frv_legitimate_address_p (mode, addr, reload_completed, TRUE, FALSE);
05365 }
05366 
05367 /* Return true if OP is an integer binary operator that can be combined
05368    with a (set ... (compare:CC_NZ ...)) pattern.  */
05369 
05370 int
05371 intop_compare_operator (rtx op, enum machine_mode mode)
05372 {
05373   if (mode != VOIDmode && GET_MODE (op) != mode)
05374     return FALSE;
05375 
05376   switch (GET_CODE (op))
05377     {
05378     default:
05379       return FALSE;
05380 
05381     case PLUS:
05382     case MINUS:
05383     case AND:
05384     case IOR:
05385     case XOR:
05386     case ASHIFTRT:
05387     case LSHIFTRT:
05388       return GET_MODE (op) == SImode;
05389     }
05390 }
05391 
05392 /* Return 1 if operand is a valid ACC register number.  */
05393 
05394 int
05395 acc_operand (rtx op, enum machine_mode mode)
05396 {
05397   return ((mode == VOIDmode || mode == GET_MODE (op))
05398     && REG_P (op) && ACC_P (REGNO (op))
05399     && ((REGNO (op) - ACC_FIRST) & ~ACC_MASK) == 0);
05400 }
05401 
05402 /* Return 1 if operand is a valid even ACC register number.  */
05403 
05404 int
05405 even_acc_operand (rtx op, enum machine_mode mode)
05406 {
05407   return acc_operand (op, mode) && ((REGNO (op) - ACC_FIRST) & 1) == 0;
05408 }
05409 
05410 /* Return 1 if operand is zero or four.  */
05411 
05412 int
05413 quad_acc_operand (rtx op, enum machine_mode mode)
05414 {
05415   return acc_operand (op, mode) && ((REGNO (op) - ACC_FIRST) & 3) == 0;
05416 }
05417 
05418 /* Return 1 if operand is a valid ACCG register number.  */
05419 
05420 int
05421 accg_operand (rtx op, enum machine_mode mode)
05422 {
05423   return ((mode == VOIDmode || mode == GET_MODE (op))
05424     && REG_P (op) && ACCG_P (REGNO (op))
05425     && ((REGNO (op) - ACCG_FIRST) & ~ACC_MASK) == 0);
05426 }
05427 
05428 
05429 /* Return true if the bare return instruction can be used outside of the
05430    epilog code.  For frv, we only do it if there was no stack allocation.  */
05431 
05432 int
05433 direct_return_p (void)
05434 {
05435   frv_stack_t *info;
05436 
05437   if (!reload_completed)
05438     return FALSE;
05439 
05440   info = frv_stack_info ();
05441   return (info->total_size == 0);
05442 }
05443 
05444 
05445 void
05446 frv_emit_move (enum machine_mode mode, rtx dest, rtx src)
05447 {
05448   if (GET_CODE (src) == SYMBOL_REF)
05449     {
05450       enum tls_model model = SYMBOL_REF_TLS_MODEL (src);
05451       if (model != 0)
05452   src = frv_legitimize_tls_address (src, model);
05453     }
05454 
05455   switch (mode)
05456     {
05457     case SImode:
05458       if (frv_emit_movsi (dest, src))
05459   return;
05460       break;
05461 
05462     case QImode:
05463     case HImode:
05464     case DImode:
05465     case SFmode:
05466     case DFmode:
05467       if (!reload_in_progress
05468     && !reload_completed
05469     && !register_operand (dest, mode)
05470     && !reg_or_0_operand (src, mode))
05471   src = copy_to_mode_reg (mode, src);
05472       break;
05473 
05474     default:
05475       abort ();
05476     }
05477 
05478   emit_insn (gen_rtx_SET (VOIDmode, dest, src));
05479 }
05480 
05481 /* Emit code to handle a MOVSI, adding in the small data register or pic
05482    register if needed to load up addresses.  Return TRUE if the appropriate
05483    instructions are emitted.  */
05484 
05485 int
05486 frv_emit_movsi (rtx dest, rtx src)
05487 {
05488   int base_regno = -1;
05489   int unspec = 0;
05490   rtx sym = src;
05491   struct frv_unspec old_unspec;
05492 
05493   if (!reload_in_progress
05494       && !reload_completed
05495       && !register_operand (dest, SImode)
05496       && (!reg_or_0_operand (src, SImode)
05497        /* Virtual registers will almost always be replaced by an
05498     add instruction, so expose this to CSE by copying to
05499     an intermediate register.  */
05500     || (GET_CODE (src) == REG
05501         && IN_RANGE_P (REGNO (src),
05502            FIRST_VIRTUAL_REGISTER,
05503            LAST_VIRTUAL_REGISTER))))
05504     {
05505       emit_insn (gen_rtx_SET (VOIDmode, dest, copy_to_mode_reg (SImode, src)));
05506       return TRUE;
05507     }
05508 
05509   /* Explicitly add in the PIC or small data register if needed.  */
05510   switch (GET_CODE (src))
05511     {
05512     default:
05513       break;
05514 
05515     case LABEL_REF:
05516     handle_label:
05517       if (TARGET_FDPIC)
05518   {
05519     /* Using GPREL12, we use a single GOT entry for all symbols
05520        in read-only sections, but trade sequences such as:
05521 
05522        sethi #gothi(label), gr#
05523        setlo #gotlo(label), gr#
05524        ld    @(gr15,gr#), gr#
05525 
05526        for
05527 
05528        ld    @(gr15,#got12(_gp)), gr#
05529        sethi #gprelhi(label), gr##
05530        setlo #gprello(label), gr##
05531        add   gr#, gr##, gr##
05532 
05533        We may often be able to share gr# for multiple
05534        computations of GPREL addresses, and we may often fold
05535        the final add into the pair of registers of a load or
05536        store instruction, so it's often profitable.  Even when
05537        optimizing for size, we're trading a GOT entry for an
05538        additional instruction, which trades GOT space
05539        (read-write) for code size (read-only, shareable), as
05540        long as the symbol is not used in more than two different
05541        locations.
05542        
05543        With -fpie/-fpic, we'd be trading a single load for a
05544        sequence of 4 instructions, because the offset of the
05545        label can't be assumed to be addressable with 12 bits, so
05546        we don't do this.  */
05547     if (TARGET_GPREL_RO)
05548       unspec = R_FRV_GPREL12;
05549     else
05550       unspec = R_FRV_GOT12;
05551   }
05552       else if (flag_pic)
05553   base_regno = PIC_REGNO;
05554 
05555       break;
05556 
05557     case CONST:
05558       if (frv_const_unspec_p (src, &old_unspec))
05559   break;
05560 
05561       if (TARGET_FDPIC && frv_function_symbol_referenced_p (XEXP (src, 0)))
05562   {
05563   handle_whatever:
05564     src = force_reg (GET_MODE (XEXP (src, 0)), XEXP (src, 0));
05565     emit_move_insn (dest, src);
05566     return TRUE;
05567   }
05568       else
05569   {
05570     sym = XEXP (sym, 0);
05571     if (GET_CODE (sym) == PLUS
05572         && GET_CODE (XEXP (sym, 0)) == SYMBOL_REF
05573         && GET_CODE (XEXP (sym, 1)) == CONST_INT)
05574       sym = XEXP (sym, 0);
05575     if (GET_CODE (sym) == SYMBOL_REF)
05576       goto handle_sym;
05577     else if (GET_CODE (sym) == LABEL_REF)
05578       goto handle_label;
05579     else
05580       goto handle_whatever;
05581   }
05582       break;
05583 
05584     case SYMBOL_REF:
05585     handle_sym:
05586       if (TARGET_FDPIC)
05587   {
05588     enum tls_model model = SYMBOL_REF_TLS_MODEL (sym);
05589 
05590     if (model != 0)
05591       {
05592         src = frv_legitimize_tls_address (src, model);
05593         emit_move_insn (dest, src);
05594         return TRUE;
05595       }
05596 
05597     if (SYMBOL_REF_FUNCTION_P (sym))
05598       {
05599         if (frv_local_funcdesc_p (sym))
05600     unspec = R_FRV_FUNCDESC_GOTOFF12;
05601         else
05602     unspec = R_FRV_FUNCDESC_GOT12;
05603       }
05604     else
05605       {
05606         if (CONSTANT_POOL_ADDRESS_P (sym))
05607     switch (GET_CODE (get_pool_constant (sym)))
05608       {
05609       case CONST:
05610       case SYMBOL_REF:
05611       case LABEL_REF:
05612         if (flag_pic)
05613           {
05614       unspec = R_FRV_GOTOFF12;
05615       break;
05616           }
05617         /* Fall through.  */
05618       default:
05619         if (TARGET_GPREL_RO)
05620           unspec = R_FRV_GPREL12;
05621         else
05622           unspec = R_FRV_GOT12;
05623         break;
05624       }
05625         else if (SYMBOL_REF_LOCAL_P (sym)
05626            && !SYMBOL_REF_EXTERNAL_P (sym)
05627            && SYMBOL_REF_DECL (sym)
05628            && (!DECL_P (SYMBOL_REF_DECL (sym))
05629          || !DECL_COMMON (SYMBOL_REF_DECL (sym))))
05630     {
05631       tree decl = SYMBOL_REF_DECL (sym);
05632       tree init = TREE_CODE (decl) == VAR_DECL
05633         ? DECL_INITIAL (decl)
05634         : TREE_CODE (decl) == CONSTRUCTOR
05635         ? decl : 0;
05636       int reloc = 0;
05637       bool named_section, readonly;
05638 
05639       if (init && init != error_mark_node)
05640         reloc = compute_reloc_for_constant (init);
05641       
05642       named_section = TREE_CODE (decl) == VAR_DECL
05643         && lookup_attribute ("section", DECL_ATTRIBUTES (decl));
05644       readonly = decl_readonly_section (decl, reloc);
05645       
05646       if (named_section)
05647         unspec = R_FRV_GOT12;
05648       else if (!readonly)
05649         unspec = R_FRV_GOTOFF12;
05650       else if (readonly && TARGET_GPREL_RO)
05651         unspec = R_FRV_GPREL12;
05652       else
05653         unspec = R_FRV_GOT12;
05654     }
05655         else
05656     unspec = R_FRV_GOT12;
05657       }
05658   }
05659 
05660       else if (SYMBOL_REF_SMALL_P (sym))
05661   base_regno = SDA_BASE_REG;
05662 
05663       else if (flag_pic)
05664   base_regno = PIC_REGNO;
05665 
05666       break;
05667     }
05668 
05669   if (base_regno >= 0)
05670     {
05671       if (GET_CODE (sym) == SYMBOL_REF && SYMBOL_REF_SMALL_P (sym))
05672   emit_insn (gen_symGOTOFF2reg (dest, src,
05673               gen_rtx_REG (Pmode, base_regno),
05674               GEN_INT (R_FRV_GPREL12)));
05675       else
05676   emit_insn (gen_symGOTOFF2reg_hilo (dest, src,
05677              gen_rtx_REG (Pmode, base_regno),
05678              GEN_INT (R_FRV_GPREL12)));
05679       if (base_regno == PIC_REGNO)
05680   cfun->uses_pic_offset_table = TRUE;
05681       return TRUE;
05682     }
05683 
05684   if (unspec)
05685     {
05686       rtx x;
05687 
05688       /* Since OUR_FDPIC_REG is a pseudo register, we can't safely introduce
05689    new uses of it once reload has begun.  */
05690       if (reload_in_progress || reload_completed)
05691   abort ();
05692 
05693       switch (unspec)
05694   {
05695   case R_FRV_GOTOFF12:
05696     if (!frv_small_data_reloc_p (sym, unspec))
05697       x = gen_symGOTOFF2reg_hilo (dest, src, OUR_FDPIC_REG,
05698           GEN_INT (unspec));
05699     else
05700       x = gen_symGOTOFF2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
05701     break;
05702   case R_FRV_GPREL12:
05703     if (!frv_small_data_reloc_p (sym, unspec))
05704       x = gen_symGPREL2reg_hilo (dest, src, OUR_FDPIC_REG,
05705                GEN_INT (unspec));
05706     else
05707       x = gen_symGPREL2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
05708     break;
05709   case R_FRV_FUNCDESC_GOTOFF12:
05710     if (flag_pic != 1)
05711       x = gen_symGOTOFF2reg_hilo (dest, src, OUR_FDPIC_REG,
05712           GEN_INT (unspec));
05713     else
05714       x = gen_symGOTOFF2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
05715     break;
05716   default:
05717     if (flag_pic != 1)
05718       x = gen_symGOT2reg_hilo (dest, src, OUR_FDPIC_REG,
05719              GEN_INT (unspec));
05720     else
05721       x = gen_symGOT2reg (dest, src, OUR_FDPIC_REG, GEN_INT (unspec));
05722     break;
05723   }
05724       emit_insn (x);
05725       cfun->uses_pic_offset_table = TRUE;
05726       return TRUE;
05727     }
05728 
05729 
05730   return FALSE;
05731 }
05732 
05733 
05734 /* Return a string to output a single word move.  */
05735 
05736 const char *
05737 output_move_single (rtx operands[], rtx insn)
05738 {
05739   rtx dest = operands[0];
05740   rtx src  = operands[1];
05741 
05742   if (GET_CODE (dest) == REG)
05743     {
05744       int dest_regno = REGNO (dest);
05745       enum machine_mode mode = GET_MODE (dest);
05746 
05747       if (GPR_P (dest_regno))
05748   {
05749     if (GET_CODE (src) == REG)
05750       {
05751         /* gpr <- some sort of register */
05752         int src_regno = REGNO (src);
05753 
05754         if (GPR_P (src_regno))
05755     return "mov %1, %0";
05756 
05757         else if (FPR_P (src_regno))
05758     return "movfg %1, %0";
05759 
05760         else if (SPR_P (src_regno))
05761     return "movsg %1, %0";
05762       }
05763 
05764     else if (GET_CODE (src) == MEM)
05765       {
05766         /* gpr <- memory */
05767         switch (mode)
05768     {
05769     default:
05770       break;
05771 
05772     case QImode:
05773       return "ldsb%I1%U1 %M1,%0";
05774 
05775     case HImode:
05776       return "ldsh%I1%U1 %M1,%0";
05777 
05778     case SImode:
05779     case SFmode:
05780       return "ld%I1%U1 %M1, %0";
05781     }
05782       }
05783 
05784     else if (GET_CODE (src) == CONST_INT
05785        || GET_CODE (src) == CONST_DOUBLE)
05786       {
05787         /* gpr <- integer/floating constant */
05788         HOST_WIDE_INT value;
05789 
05790         if (GET_CODE (src) == CONST_INT)
05791     value = INTVAL (src);
05792 
05793         else if (mode == SFmode)
05794     {
05795       REAL_VALUE_TYPE rv;
05796       long l;
05797 
05798       REAL_VALUE_FROM_CONST_DOUBLE (rv, src);
05799       REAL_VALUE_TO_TARGET_SINGLE (rv, l);
05800       value = l;
05801     }
05802 
05803         else
05804     value = CONST_DOUBLE_LOW (src);
05805 
05806         if (IN_RANGE_P (value, -32768, 32767))
05807     return "setlos %1, %0";
05808 
05809         return "#";
05810       }
05811 
05812           else if (GET_CODE (src) == SYMBOL_REF
05813        || GET_CODE (src) == LABEL_REF
05814        || GET_CODE (src) == CONST)
05815       {
05816         return "#";
05817       }
05818   }
05819 
05820       else if (FPR_P (dest_regno))
05821   {
05822     if (GET_CODE (src) == REG)
05823       {
05824         /* fpr <- some sort of register */
05825         int src_regno = REGNO (src);
05826 
05827         if (GPR_P (src_regno))
05828     return "movgf %1, %0";
05829 
05830         else if (FPR_P (src_regno))
05831     {
05832       if (TARGET_HARD_FLOAT)
05833         return "fmovs %1, %0";
05834       else
05835         return "mor %1, %1, %0";
05836     }
05837       }
05838 
05839     else if (GET_CODE (src) == MEM)
05840       {
05841         /* fpr <- memory */
05842         switch (mode)
05843     {
05844     default:
05845       break;
05846 
05847     case QImode:
05848       return "ldbf%I1%U1 %M1,%0";
05849 
05850     case HImode:
05851       return "ldhf%I1%U1 %M1,%0";
05852 
05853     case SImode:
05854     case SFmode:
05855       return "ldf%I1%U1 %M1, %0";
05856     }
05857       }
05858 
05859     else if (ZERO_P (src))
05860       return "movgf %., %0";
05861   }
05862 
05863       else if (SPR_P (dest_regno))
05864   {
05865     if (GET_CODE (src) == REG)
05866       {
05867         /* spr <- some sort of register */
05868         int src_regno = REGNO (src);
05869 
05870         if (GPR_P (src_regno))
05871     return "movgs %1, %0";
05872       }
05873     else if (ZERO_P (src))
05874       return "movgs %., %0";
05875   }
05876     }
05877 
05878   else if (GET_CODE (dest) == MEM)
05879     {
05880       if (GET_CODE (src) == REG)
05881   {
05882     int src_regno = REGNO (src);
05883     enum machine_mode mode = GET_MODE (dest);
05884 
05885     if (GPR_P (src_regno))
05886       {
05887         switch (mode)
05888     {
05889     default:
05890       break;
05891 
05892     case QImode:
05893       return "stb%I0%U0 %1, %M0";
05894 
05895     case HImode:
05896       return "sth%I0%U0 %1, %M0";
05897 
05898     case SImode:
05899     case SFmode:
05900       return "st%I0%U0 %1, %M0";
05901     }
05902       }
05903 
05904     else if (FPR_P (src_regno))
05905       {
05906         switch (mode)
05907     {
05908     default:
05909       break;
05910 
05911     case QImode:
05912       return "stbf%I0%U0 %1, %M0";
05913 
05914     case HImode:
05915       return "sthf%I0%U0 %1, %M0";
05916 
05917     case SImode:
05918     case SFmode:
05919       return "stf%I0%U0 %1, %M0";
05920     }
05921       }
05922   }
05923 
05924       else if (ZERO_P (src))
05925   {
05926     switch (GET_MODE (dest))
05927       {
05928       default:
05929         break;
05930 
05931       case QImode:
05932         return "stb%I0%U0 %., %M0";
05933 
05934       case HImode:
05935         return "sth%I0%U0 %., %M0";
05936 
05937       case SImode:
05938       case SFmode:
05939         return "st%I0%U0 %., %M0";
05940       }
05941   }
05942     }
05943 
05944   fatal_insn ("Bad output_move_single operand", insn);
05945   return "";
05946 }
05947 
05948 
05949 /* Return a string to output a double word move.  */
05950 
05951 const char *
05952 output_move_double (rtx operands[], rtx insn)
05953 {
05954   rtx dest = operands[0];
05955   rtx src  = operands[1];
05956   enum machine_mode mode = GET_MODE (dest);
05957 
05958   if (GET_CODE (dest) == REG)
05959     {
05960       int dest_regno = REGNO (dest);
05961 
05962       if (GPR_P (dest_regno))
05963   {
05964     if (GET_CODE (src) == REG)
05965       {
05966         /* gpr <- some sort of register */
05967         int src_regno = REGNO (src);
05968 
05969         if (GPR_P (src_regno))
05970     return "#";
05971 
05972         else if (FPR_P (src_regno))
05973     {
05974       if (((dest_regno - GPR_FIRST) & 1) == 0
05975           && ((src_regno - FPR_FIRST) & 1) == 0)
05976         return "movfgd %1, %0";
05977 
05978       return "#";
05979     }
05980       }
05981 
05982     else if (GET_CODE (src) == MEM)
05983       {
05984         /* gpr <- memory */
05985         if (dbl_memory_one_insn_operand (src, mode))
05986     return "ldd%I1%U1 %M1, %0";
05987 
05988         return "#";
05989       }
05990 
05991     else if (GET_CODE (src) == CONST_INT
05992        || GET_CODE (src) == CONST_DOUBLE)
05993       return "#";
05994   }
05995 
05996       else if (FPR_P (dest_regno))
05997   {
05998     if (GET_CODE (src) == REG)
05999       {
06000         /* fpr <- some sort of register */
06001         int src_regno = REGNO (src);
06002 
06003         if (GPR_P (src_regno))
06004     {
06005       if (((dest_regno - FPR_FIRST) & 1) == 0
06006           && ((src_regno - GPR_FIRST) & 1) == 0)
06007         return "movgfd %1, %0";
06008 
06009       return "#";
06010     }
06011 
06012         else if (FPR_P (src_regno))
06013     {
06014       if (TARGET_DOUBLE
06015           && ((dest_regno - FPR_FIRST) & 1) == 0
06016           && ((src_regno - FPR_FIRST) & 1) == 0)
06017         return "fmovd %1, %0";
06018 
06019       return "#";
06020     }
06021       }
06022 
06023     else if (GET_CODE (src) == MEM)
06024       {
06025         /* fpr <- memory */
06026         if (dbl_memory_one_insn_operand (src, mode))
06027     return "lddf%I1%U1 %M1, %0";
06028 
06029         return "#";
06030       }
06031 
06032     else if (ZERO_P (src))
06033       return "#";
06034   }
06035     }
06036 
06037   else if (GET_CODE (dest) == MEM)
06038     {
06039       if (GET_CODE (src) == REG)
06040   {
06041     int src_regno = REGNO (src);
06042 
06043     if (GPR_P (src_regno))
06044       {
06045         if (((src_regno - GPR_FIRST) & 1) == 0
06046       && dbl_memory_one_insn_operand (dest, mode))
06047     return "std%I0%U0 %1, %M0";
06048 
06049         return "#";
06050       }
06051 
06052     if (FPR_P (src_regno))
06053       {
06054         if (((src_regno - FPR_FIRST) & 1) == 0
06055       && dbl_memory_one_insn_operand (dest, mode))
06056     return "stdf%I0%U0 %1, %M0";
06057 
06058         return "#";
06059       }
06060   }
06061 
06062       else if (ZERO_P (src))
06063   {
06064     if (dbl_memory_one_insn_operand (dest, mode))
06065       return "std%I0%U0 %., %M0";
06066 
06067     return "#";
06068   }
06069     }
06070 
06071   fatal_insn ("Bad output_move_double operand", insn);
06072   return "";
06073 }
06074 
06075 
06076 /* Return a string to output a single word conditional move.
06077    Operand0 -- EQ/NE of ccr register and 0
06078    Operand1 -- CCR register
06079    Operand2 -- destination
06080    Operand3 -- source  */
06081 
06082 const char *
06083 output_condmove_single (rtx operands[], rtx insn)
06084 {
06085   rtx dest = operands[2];
06086   rtx src  = operands[3];
06087 
06088   if (GET_CODE (dest) == REG)
06089     {
06090       int dest_regno = REGNO (dest);
06091       enum machine_mode mode = GET_MODE (dest);
06092 
06093       if (GPR_P (dest_regno))
06094   {
06095     if (GET_CODE (src) == REG)
06096       {
06097         /* gpr <- some sort of register */
06098         int src_regno = REGNO (src);
06099 
06100         if (GPR_P (src_regno))
06101     return "cmov %z3, %2, %1, %e0";
06102 
06103         else if (FPR_P (src_regno))
06104     return "cmovfg %3, %2, %1, %e0";
06105       }
06106 
06107     else if (GET_CODE (src) == MEM)
06108       {
06109         /* gpr <- memory */
06110         switch (mode)
06111     {
06112     default:
06113       break;
06114 
06115     case QImode:
06116       return "cldsb%I3%U3 %M3, %2, %1, %e0";
06117 
06118     case HImode:
06119       return "cldsh%I3%U3 %M3, %2, %1, %e0";
06120 
06121     case SImode:
06122     case SFmode:
06123       return "cld%I3%U3 %M3, %2, %1, %e0";
06124     }
06125       }
06126 
06127     else if (ZERO_P (src))
06128       return "cmov %., %2, %1, %e0";
06129   }
06130 
06131       else if (FPR_P (dest_regno))
06132   {
06133     if (GET_CODE (src) == REG)
06134       {
06135         /* fpr <- some sort of register */
06136         int src_regno = REGNO (src);
06137 
06138         if (GPR_P (src_regno))
06139     return "cmovgf %3, %2, %1, %e0";
06140 
06141         else if (FPR_P (src_regno))
06142     {
06143       if (TARGET_HARD_FLOAT)
06144         return "cfmovs %3,%2,%1,%e0";
06145       else
06146         return "cmor %3, %3, %2, %1, %e0";
06147     }
06148       }
06149 
06150     else if (GET_CODE (src) == MEM)
06151       {
06152         /* fpr <- memory */
06153         if (mode == SImode || mode == SFmode)
06154     return "cldf%I3%U3 %M3, %2, %1, %e0";
06155       }
06156 
06157     else if (ZERO_P (src))
06158       return "cmovgf %., %2, %1, %e0";
06159   }
06160     }
06161 
06162   else if (GET_CODE (dest) == MEM)
06163     {
06164       if (GET_CODE (src) == REG)
06165   {
06166     int src_regno = REGNO (src);
06167     enum machine_mode mode = GET_MODE (dest);
06168 
06169     if (GPR_P (src_regno))
06170       {
06171         switch (mode)
06172     {
06173     default:
06174       break;
06175 
06176     case QImode:
06177       return "cstb%I2%U2 %3, %M2, %1, %e0";
06178 
06179     case HImode:
06180       return "csth%I2%U2 %3, %M2, %1, %e0";
06181 
06182     case SImode:
06183     case SFmode:
06184       return "cst%I2%U2 %3, %M2, %1, %e0";
06185     }
06186       }
06187 
06188     else if (FPR_P (src_regno) && (mode == SImode || mode == SFmode))
06189       return "cstf%I2%U2 %3, %M2, %1, %e0";
06190   }
06191 
06192       else if (ZERO_P (src))
06193   {
06194     enum machine_mode mode = GET_MODE (dest);
06195     switch (mode)
06196       {
06197       default:
06198         break;
06199 
06200       case QImode:
06201         return "cstb%I2%U2 %., %M2, %1, %e0";
06202 
06203       case HImode:
06204         return "csth%I2%U2 %., %M2, %1, %e0";
06205 
06206       case SImode:
06207       case SFmode:
06208         return "cst%I2%U2 %., %M2, %1, %e0";
06209       }
06210   }
06211     }
06212 
06213   fatal_insn ("Bad output_condmove_single operand", insn);
06214   return "";
06215 }
06216 
06217 
06218 /* Emit the appropriate code to do a comparison, returning the register the
06219    comparison was done it.  */
06220 
06221 static rtx
06222 frv_emit_comparison (enum rtx_code test, rtx op0, rtx op1)
06223 {
06224   enum machine_mode cc_mode;
06225   rtx cc_reg;
06226 
06227   /* Floating point doesn't have comparison against a constant.  */
06228   if (GET_MODE (op0) == CC_FPmode && GET_CODE (op1) != REG)
06229     op1 = force_reg (GET_MODE (op0), op1);
06230 
06231   /* Possibly disable using anything but a fixed register in order to work
06232      around cse moving comparisons past function calls.  */
06233   cc_mode = SELECT_CC_MODE (test, op0, op1);
06234   cc_reg = ((TARGET_ALLOC_CC)
06235       ? gen_reg_rtx (cc_mode)
06236       : gen_rtx_REG (cc_mode,
06237          (cc_mode == CC_FPmode) ? FCC_FIRST : ICC_FIRST));
06238 
06239   emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
06240         gen_rtx_COMPARE (cc_mode, op0, op1)));
06241 
06242   return cc_reg;
06243 }
06244 
06245 
06246 /* Emit code for a conditional branch.  The comparison operands were previously
06247    stored in frv_compare_op0 and frv_compare_op1.
06248 
06249    XXX: I originally wanted to add a clobber of a CCR register to use in
06250    conditional execution, but that confuses the rest of the compiler.  */
06251 
06252 int
06253 frv_emit_cond_branch (enum rtx_code test, rtx label)
06254 {
06255   rtx test_rtx;
06256   rtx label_ref;
06257   rtx if_else;
06258   rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
06259   enum machine_mode cc_mode = GET_MODE (cc_reg);
06260 
06261   /* Branches generate:
06262   (set (pc)
06263        (if_then_else (<test>, <cc_reg>, (const_int 0))
06264           (label_ref <branch_label>)
06265           (pc))) */
06266   label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
06267   test_rtx = gen_rtx_fmt_ee (test, cc_mode, cc_reg, const0_rtx);
06268   if_else = gen_rtx_IF_THEN_ELSE (cc_mode, test_rtx, label_ref, pc_rtx);
06269   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_else));
06270   return TRUE;
06271 }
06272 
06273 
06274 /* Emit code to set a gpr to 1/0 based on a comparison.  The comparison
06275    operands were previously stored in frv_compare_op0 and frv_compare_op1.  */
06276 
06277 int
06278 frv_emit_scc (enum rtx_code test, rtx target)
06279 {
06280   rtx set;
06281   rtx test_rtx;
06282   rtx clobber;
06283   rtx cr_reg;
06284   rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
06285 
06286   /* SCC instructions generate:
06287   (parallel [(set <target> (<test>, <cc_reg>, (const_int 0))
06288        (clobber (<ccr_reg>))])  */
06289   test_rtx = gen_rtx_fmt_ee (test, SImode, cc_reg, const0_rtx);
06290   set = gen_rtx_SET (VOIDmode, target, test_rtx);
06291 
06292   cr_reg = ((TARGET_ALLOC_CC)
06293       ? gen_reg_rtx (CC_CCRmode)
06294       : gen_rtx_REG (CC_CCRmode,
06295          ((GET_MODE (cc_reg) == CC_FPmode)
06296           ? FCR_FIRST
06297           : ICR_FIRST)));
06298 
06299   clobber = gen_rtx_CLOBBER (VOIDmode, cr_reg);
06300   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber)));
06301   return TRUE;
06302 }
06303 
06304 
06305 /* Split a SCC instruction into component parts, returning a SEQUENCE to hold
06306    the separate insns.  */
06307 
06308 rtx
06309 frv_split_scc (rtx dest, rtx test, rtx cc_reg, rtx cr_reg, HOST_WIDE_INT value)
06310 {
06311   rtx ret;
06312 
06313   start_sequence ();
06314 
06315   /* Set the appropriate CCR bit.  */
06316   emit_insn (gen_rtx_SET (VOIDmode,
06317         cr_reg,
06318         gen_rtx_fmt_ee (GET_CODE (test),
06319             GET_MODE (cr_reg),
06320             cc_reg,
06321             const0_rtx)));
06322 
06323   /* Move the value into the destination.  */
06324   emit_move_insn (dest, GEN_INT (value));
06325 
06326   /* Move 0 into the destination if the test failed */
06327   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06328         gen_rtx_EQ (GET_MODE (cr_reg),
06329               cr_reg,
06330               const0_rtx),
06331         gen_rtx_SET (VOIDmode, dest, const0_rtx)));
06332 
06333   /* Finish up, return sequence.  */
06334   ret = get_insns ();
06335   end_sequence ();
06336   return ret;
06337 }
06338 
06339 
06340 /* Emit the code for a conditional move, return TRUE if we could do the
06341    move.  */
06342 
06343 int
06344 frv_emit_cond_move (rtx dest, rtx test_rtx, rtx src1, rtx src2)
06345 {
06346   rtx set;
06347   rtx clobber_cc;
06348   rtx test2;
06349   rtx cr_reg;
06350   rtx if_rtx;
06351   enum rtx_code test = GET_CODE (test_rtx);
06352   rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
06353   enum machine_mode cc_mode = GET_MODE (cc_reg);
06354 
06355   /* Conditional move instructions generate:
06356   (parallel [(set <target>
06357       (if_then_else (<test> <cc_reg> (const_int 0))
06358               <src1>
06359               <src2>))
06360        (clobber (<ccr_reg>))])  */
06361 
06362   /* Handle various cases of conditional move involving two constants.  */
06363   if (GET_CODE (src1) == CONST_INT && GET_CODE (src2) == CONST_INT)
06364     {
06365       HOST_WIDE_INT value1 = INTVAL (src1);
06366       HOST_WIDE_INT value2 = INTVAL (src2);
06367 
06368       /* Having 0 as one of the constants can be done by loading the other
06369          constant, and optionally moving in gr0.  */
06370       if (value1 == 0 || value2 == 0)
06371   ;
06372 
06373       /* If the first value is within an addi range and also the difference
06374          between the two fits in an addi's range, load up the difference, then
06375          conditionally move in 0, and then unconditionally add the first
06376    value.  */
06377       else if (IN_RANGE_P (value1, -2048, 2047)
06378          && IN_RANGE_P (value2 - value1, -2048, 2047))
06379   ;
06380 
06381       /* If neither condition holds, just force the constant into a
06382    register.  */
06383       else
06384   {
06385     src1 = force_reg (GET_MODE (dest), src1);
06386     src2 = force_reg (GET_MODE (dest), src2);
06387   }
06388     }
06389 
06390   /* If one value is a register, insure the other value is either 0 or a
06391      register.  */
06392   else
06393     {
06394       if (GET_CODE (src1) == CONST_INT && INTVAL (src1) != 0)
06395   src1 = force_reg (GET_MODE (dest), src1);
06396 
06397       if (GET_CODE (src2) == CONST_INT && INTVAL (src2) != 0)
06398   src2 = force_reg (GET_MODE (dest), src2);
06399     }
06400 
06401   test2 = gen_rtx_fmt_ee (test, cc_mode, cc_reg, const0_rtx);
06402   if_rtx = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), test2, src1, src2);
06403 
06404   set = gen_rtx_SET (VOIDmode, dest, if_rtx);
06405 
06406   cr_reg = ((TARGET_ALLOC_CC)
06407       ? gen_reg_rtx (CC_CCRmode)
06408       : gen_rtx_REG (CC_CCRmode,
06409          (cc_mode == CC_FPmode) ? FCR_FIRST : ICR_FIRST));
06410 
06411   clobber_cc = gen_rtx_CLOBBER (VOIDmode, cr_reg);
06412   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber_cc)));
06413   return TRUE;
06414 }
06415 
06416 
06417 /* Split a conditional move into constituent parts, returning a SEQUENCE
06418    containing all of the insns.  */
06419 
06420 rtx
06421 frv_split_cond_move (rtx operands[])
06422 {
06423   rtx dest  = operands[0];
06424   rtx test  = operands[1];
06425   rtx cc_reg  = operands[2];
06426   rtx src1  = operands[3];
06427   rtx src2  = operands[4];
06428   rtx cr_reg  = operands[5];
06429   rtx ret;
06430   enum machine_mode cr_mode = GET_MODE (cr_reg);
06431 
06432   start_sequence ();
06433 
06434   /* Set the appropriate CCR bit.  */
06435   emit_insn (gen_rtx_SET (VOIDmode,
06436         cr_reg,
06437         gen_rtx_fmt_ee (GET_CODE (test),
06438             GET_MODE (cr_reg),
06439             cc_reg,
06440             const0_rtx)));
06441 
06442   /* Handle various cases of conditional move involving two constants.  */
06443   if (GET_CODE (src1) == CONST_INT && GET_CODE (src2) == CONST_INT)
06444     {
06445       HOST_WIDE_INT value1 = INTVAL (src1);
06446       HOST_WIDE_INT value2 = INTVAL (src2);
06447 
06448       /* Having 0 as one of the constants can be done by loading the other
06449          constant, and optionally moving in gr0.  */
06450       if (value1 == 0)
06451   {
06452     emit_move_insn (dest, src2);
06453     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06454           gen_rtx_NE (cr_mode, cr_reg,
06455                 const0_rtx),
06456           gen_rtx_SET (VOIDmode, dest, src1)));
06457   }
06458 
06459       else if (value2 == 0)
06460   {
06461     emit_move_insn (dest, src1);
06462     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06463           gen_rtx_EQ (cr_mode, cr_reg,
06464                 const0_rtx),
06465           gen_rtx_SET (VOIDmode, dest, src2)));
06466   }
06467 
06468       /* If the first value is within an addi range and also the difference
06469          between the two fits in an addi's range, load up the difference, then
06470          conditionally move in 0, and then unconditionally add the first
06471    value.  */
06472       else if (IN_RANGE_P (value1, -2048, 2047)
06473          && IN_RANGE_P (value2 - value1, -2048, 2047))
06474   {
06475     rtx dest_si = ((GET_MODE (dest) == SImode)
06476        ? dest
06477        : gen_rtx_SUBREG (SImode, dest, 0));
06478 
06479     emit_move_insn (dest_si, GEN_INT (value2 - value1));
06480     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06481           gen_rtx_NE (cr_mode, cr_reg,
06482                 const0_rtx),
06483           gen_rtx_SET (VOIDmode, dest_si,
06484                  const0_rtx)));
06485     emit_insn (gen_addsi3 (dest_si, dest_si, src1));
06486   }
06487 
06488       else
06489   abort ();
06490     }
06491   else
06492     {
06493       /* Emit the conditional move for the test being true if needed.  */
06494       if (! rtx_equal_p (dest, src1))
06495   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06496               gen_rtx_NE (cr_mode, cr_reg, const0_rtx),
06497               gen_rtx_SET (VOIDmode, dest, src1)));
06498 
06499       /* Emit the conditional move for the test being false if needed.  */
06500       if (! rtx_equal_p (dest, src2))
06501   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06502               gen_rtx_EQ (cr_mode, cr_reg, const0_rtx),
06503               gen_rtx_SET (VOIDmode, dest, src2)));
06504     }
06505 
06506   /* Finish up, return sequence.  */
06507   ret = get_insns ();
06508   end_sequence ();
06509   return ret;
06510 }
06511 
06512 
06513 /* Split (set DEST SOURCE), where DEST is a double register and SOURCE is a
06514    memory location that is not known to be dword-aligned.  */
06515 void
06516 frv_split_double_load (rtx dest, rtx source)
06517 {
06518   int regno = REGNO (dest);
06519   rtx dest1 = gen_highpart (SImode, dest);
06520   rtx dest2 = gen_lowpart (SImode, dest);
06521   rtx address = XEXP (source, 0);
06522 
06523   /* If the address is pre-modified, load the lower-numbered register
06524      first, then load the other register using an integer offset from
06525      the modified base register.  This order should always be safe,
06526      since the pre-modification cannot affect the same registers as the
06527      load does.
06528 
06529      The situation for other loads is more complicated.  Loading one
06530      of the registers could affect the value of ADDRESS, so we must
06531      be careful which order we do them in.  */
06532   if (GET_CODE (address) == PRE_MODIFY
06533       || ! refers_to_regno_p (regno, regno + 1, address, NULL))
06534     {
06535       /* It is safe to load the lower-numbered register first.  */
06536       emit_move_insn (dest1, change_address (source, SImode, NULL));
06537       emit_move_insn (dest2, frv_index_memory (source, SImode, 1));
06538     }
06539   else
06540     {
06541       /* ADDRESS is not pre-modified and the address depends on the
06542          lower-numbered register.  Load the higher-numbered register
06543          first.  */
06544       emit_move_insn (dest2, frv_index_memory (source, SImode, 1));
06545       emit_move_insn (dest1, change_address (source, SImode, NULL));
06546     }
06547 }
06548 
06549 /* Split (set DEST SOURCE), where DEST refers to a dword memory location
06550    and SOURCE is either a double register or the constant zero.  */
06551 void
06552 frv_split_double_store (rtx dest, rtx source)
06553 {
06554   rtx dest1 = change_address (dest, SImode, NULL);
06555   rtx dest2 = frv_index_memory (dest, SImode, 1);
06556   if (ZERO_P (source))
06557     {
06558       emit_move_insn (dest1, CONST0_RTX (SImode));
06559       emit_move_insn (dest2, CONST0_RTX (SImode));
06560     }
06561   else
06562     {
06563       emit_move_insn (dest1, gen_highpart (SImode, source));
06564       emit_move_insn (dest2, gen_lowpart (SImode, source));
06565     }
06566 }
06567 
06568 
06569 /* Split a min/max operation returning a SEQUENCE containing all of the
06570    insns.  */
06571 
06572 rtx
06573 frv_split_minmax (rtx operands[])
06574 {
06575   rtx dest  = operands[0];
06576   rtx minmax  = operands[1];
06577   rtx src1  = operands[2];
06578   rtx src2  = operands[3];
06579   rtx cc_reg  = operands[4];
06580   rtx cr_reg  = operands[5];
06581   rtx ret;
06582   enum rtx_code test_code;
06583   enum machine_mode cr_mode = GET_MODE (cr_reg);
06584 
06585   start_sequence ();
06586 
06587   /* Figure out which test to use.  */
06588   switch (GET_CODE (minmax))
06589     {
06590     default:
06591       abort ();
06592 
06593     case SMIN: test_code = LT;  break;
06594     case SMAX: test_code = GT;  break;
06595     case UMIN: test_code = LTU; break;
06596     case UMAX: test_code = GTU; break;
06597     }
06598 
06599   /* Issue the compare instruction.  */
06600   emit_insn (gen_rtx_SET (VOIDmode,
06601         cc_reg,
06602         gen_rtx_COMPARE (GET_MODE (cc_reg),
06603              src1, src2)));
06604 
06605   /* Set the appropriate CCR bit.  */
06606   emit_insn (gen_rtx_SET (VOIDmode,
06607         cr_reg,
06608         gen_rtx_fmt_ee (test_code,
06609             GET_MODE (cr_reg),
06610             cc_reg,
06611             const0_rtx)));
06612 
06613   /* If are taking the min/max of a nonzero constant, load that first, and
06614      then do a conditional move of the other value.  */
06615   if (GET_CODE (src2) == CONST_INT && INTVAL (src2) != 0)
06616     {
06617       if (rtx_equal_p (dest, src1))
06618   abort ();
06619 
06620       emit_move_insn (dest, src2);
06621       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06622             gen_rtx_NE (cr_mode, cr_reg, const0_rtx),
06623             gen_rtx_SET (VOIDmode, dest, src1)));
06624     }
06625 
06626   /* Otherwise, do each half of the move.  */
06627   else
06628     {
06629       /* Emit the conditional move for the test being true if needed.  */
06630       if (! rtx_equal_p (dest, src1))
06631   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06632               gen_rtx_NE (cr_mode, cr_reg, const0_rtx),
06633               gen_rtx_SET (VOIDmode, dest, src1)));
06634 
06635       /* Emit the conditional move for the test being false if needed.  */
06636       if (! rtx_equal_p (dest, src2))
06637   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06638               gen_rtx_EQ (cr_mode, cr_reg, const0_rtx),
06639               gen_rtx_SET (VOIDmode, dest, src2)));
06640     }
06641 
06642   /* Finish up, return sequence.  */
06643   ret = get_insns ();
06644   end_sequence ();
06645   return ret;
06646 }
06647 
06648 
06649 /* Split an integer abs operation returning a SEQUENCE containing all of the
06650    insns.  */
06651 
06652 rtx
06653 frv_split_abs (rtx operands[])
06654 {
06655   rtx dest  = operands[0];
06656   rtx src = operands[1];
06657   rtx cc_reg  = operands[2];
06658   rtx cr_reg  = operands[3];
06659   rtx ret;
06660 
06661   start_sequence ();
06662 
06663   /* Issue the compare < 0 instruction.  */
06664   emit_insn (gen_rtx_SET (VOIDmode,
06665         cc_reg,
06666         gen_rtx_COMPARE (CCmode, src, const0_rtx)));
06667 
06668   /* Set the appropriate CCR bit.  */
06669   emit_insn (gen_rtx_SET (VOIDmode,
06670         cr_reg,
06671         gen_rtx_fmt_ee (LT, CC_CCRmode, cc_reg, const0_rtx)));
06672 
06673   /* Emit the conditional negate if the value is negative.  */
06674   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06675         gen_rtx_NE (CC_CCRmode, cr_reg, const0_rtx),
06676         gen_negsi2 (dest, src)));
06677 
06678   /* Emit the conditional move for the test being false if needed.  */
06679   if (! rtx_equal_p (dest, src))
06680     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
06681           gen_rtx_EQ (CC_CCRmode, cr_reg, const0_rtx),
06682           gen_rtx_SET (VOIDmode, dest, src)));
06683 
06684   /* Finish up, return sequence.  */
06685   ret = get_insns ();
06686   end_sequence ();
06687   return ret;
06688 }
06689 
06690 
06691 /* An internal function called by for_each_rtx to clear in a hard_reg set each
06692    register used in an insn.  */
06693 
06694 static int
06695 frv_clear_registers_used (rtx *ptr, void *data)
06696 {
06697   if (GET_CODE (*ptr) == REG)
06698     {
06699       int regno = REGNO (*ptr);
06700       HARD_REG_SET *p_regs = (HARD_REG_SET *)data;
06701 
06702       if (regno < FIRST_PSEUDO_REGISTER)
06703   {
06704     int reg_max = regno + HARD_REGNO_NREGS (regno, GET_MODE (*ptr));
06705 
06706     while (regno < reg_max)
06707       {
06708         CLEAR_HARD_REG_BIT (*p_regs, regno);
06709         regno++;
06710       }
06711   }
06712     }
06713 
06714   return 0;
06715 }
06716 
06717 
06718 /* Initialize the extra fields provided by IFCVT_EXTRA_FIELDS.  */
06719 
06720 /* On the FR-V, we don't have any extra fields per se, but it is useful hook to
06721    initialize the static storage.  */
06722 void
06723 frv_ifcvt_init_extra_fields (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
06724 {
06725   frv_ifcvt.added_insns_list = NULL_RTX;
06726   frv_ifcvt.cur_scratch_regs = 0;
06727   frv_ifcvt.num_nested_cond_exec = 0;
06728   frv_ifcvt.cr_reg = NULL_RTX;
06729   frv_ifcvt.nested_cc_reg = NULL_RTX;
06730   frv_ifcvt.extra_int_cr = NULL_RTX;
06731   frv_ifcvt.extra_fp_cr = NULL_RTX;
06732   frv_ifcvt.last_nested_if_cr = NULL_RTX;
06733 }
06734 
06735 
06736 /* Internal function to add a potential insn to the list of insns to be inserted
06737    if the conditional execution conversion is successful.  */
06738 
06739 static void
06740 frv_ifcvt_add_insn (rtx pattern, rtx insn, int before_p)
06741 {
06742   rtx link = alloc_EXPR_LIST (VOIDmode, pattern, insn);
06743 
06744   link->jump = before_p;  /* Mark to add this before or after insn.  */
06745   frv_ifcvt.added_insns_list = alloc_EXPR_LIST (VOIDmode, link,
06746             frv_ifcvt.added_insns_list);
06747 
06748   if (TARGET_DEBUG_COND_EXEC)
06749     {
06750       fprintf (stderr,
06751          "\n:::::::::: frv_ifcvt_add_insn: add the following %s insn %d:\n",
06752          (before_p) ? "before" : "after",
06753          (int)INSN_UID (insn));
06754 
06755       debug_rtx (pattern);
06756     }
06757 }
06758 
06759 
06760 /* A C expression to modify the code described by the conditional if
06761    information CE_INFO, possibly updating the tests in TRUE_EXPR, and
06762    FALSE_EXPR for converting if-then and if-then-else code to conditional
06763    instructions.  Set either TRUE_EXPR or FALSE_EXPR to a null pointer if the
06764    tests cannot be converted.  */
06765 
06766 void
06767 frv_ifcvt_modify_tests (ce_if_block_t *ce_info, rtx *p_true, rtx *p_false)
06768 {
06769   basic_block test_bb = ce_info->test_bb; /* test basic block */
06770   basic_block then_bb = ce_info->then_bb; /* THEN */
06771   basic_block else_bb = ce_info->else_bb; /* ELSE or NULL */
06772   basic_block join_bb = ce_info->join_bb; /* join block or NULL */
06773   rtx true_expr = *p_true;
06774   rtx cr;
06775   rtx cc;
06776   rtx nested_cc;
06777   enum machine_mode mode = GET_MODE (true_expr);
06778   int j;
06779   basic_block *bb;
06780   int num_bb;
06781   frv_tmp_reg_t *tmp_reg = &frv_ifcvt.tmp_reg;
06782   rtx check_insn;
06783   rtx sub_cond_exec_reg;
06784   enum rtx_code code;
06785   enum rtx_code code_true;
06786   enum rtx_code code_false;
06787   enum reg_class cc_class;
06788   enum reg_class cr_class;
06789   int cc_first;
06790   int cc_last;
06791   reg_set_iterator rsi;
06792 
06793   /* Make sure we are only dealing with hard registers.  Also honor the
06794      -mno-cond-exec switch, and -mno-nested-cond-exec switches if
06795      applicable.  */
06796   if (!reload_completed || TARGET_NO_COND_EXEC
06797       || (TARGET_NO_NESTED_CE && ce_info->pass > 1))
06798     goto fail;
06799 
06800   /* Figure out which registers we can allocate for our own purposes.  Only
06801      consider registers that are not preserved across function calls and are
06802      not fixed.  However, allow the ICC/ICR temporary registers to be allocated
06803      if we did not need to use them in reloading other registers.  */
06804   memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs));
06805   COPY_HARD_REG_SET (tmp_reg->regs, call_used_reg_set);
06806   AND_COMPL_HARD_REG_SET (tmp_reg->regs, fixed_reg_set);
06807   SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP);
06808   SET_HARD_REG_BIT (tmp_reg->regs, ICR_TEMP);
06809 
06810   /* If this is a nested IF, we need to discover whether the CC registers that
06811      are set/used inside of the block are used anywhere else.  If not, we can
06812      change them to be the CC register that is paired with the CR register that
06813      controls the outermost IF block.  */
06814   if (ce_info->pass > 1)
06815     {
06816       CLEAR_HARD_REG_SET (frv_ifcvt.nested_cc_ok_rewrite);
06817       for (j = CC_FIRST; j <= CC_LAST; j++)
06818   if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
06819     {
06820       if (REGNO_REG_SET_P (then_bb->global_live_at_start, j))
06821         continue;
06822 
06823       if (else_bb && REGNO_REG_SET_P (else_bb->global_live_at_start, j))
06824         continue;
06825 
06826       if (join_bb && REGNO_REG_SET_P (join_bb->global_live_at_start, j))
06827         continue;
06828 
06829       SET_HARD_REG_BIT (frv_ifcvt.nested_cc_ok_rewrite, j);
06830     }
06831     }
06832 
06833   for (j = 0; j < frv_ifcvt.cur_scratch_regs; j++)
06834     frv_ifcvt.scratch_regs[j] = NULL_RTX;
06835 
06836   frv_ifcvt.added_insns_list = NULL_RTX;
06837   frv_ifcvt.cur_scratch_regs = 0;
06838 
06839   bb = (basic_block *) alloca ((2 + ce_info->num_multiple_test_blocks)
06840              * sizeof (basic_block));
06841 
06842   if (join_bb)
06843     {
06844       int regno;
06845 
06846       /* Remove anything live at the beginning of the join block from being
06847          available for allocation.  */
06848       EXECUTE_IF_SET_IN_REG_SET (join_bb->global_live_at_start, 0, regno, rsi)
06849   {
06850     if (regno < FIRST_PSEUDO_REGISTER)
06851       CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
06852   }
06853     }
06854 
06855   /* Add in all of the blocks in multiple &&/|| blocks to be scanned.  */
06856   num_bb = 0;
06857   if (ce_info->num_multiple_test_blocks)
06858     {
06859       basic_block multiple_test_bb = ce_info->last_test_bb;
06860 
06861       while (multiple_test_bb != test_bb)
06862   {
06863     bb[num_bb++] = multiple_test_bb;
06864     multiple_test_bb = EDGE_PRED (multiple_test_bb, 0)->src;
06865   }
06866     }
06867 
06868   /* Add in the THEN and ELSE blocks to be scanned.  */
06869   bb[num_bb++] = then_bb;
06870   if (else_bb)
06871     bb[num_bb++] = else_bb;
06872 
06873   sub_cond_exec_reg = NULL_RTX;
06874   frv_ifcvt.num_nested_cond_exec = 0;
06875 
06876   /* Scan all of the blocks for registers that must not be allocated.  */
06877   for (j = 0; j < num_bb; j++)
06878     {
06879       rtx last_insn = BB_END (bb[j]);
06880       rtx insn = BB_HEAD (bb[j]);
06881       int regno;
06882 
06883       if (dump_file)
06884   fprintf (dump_file, "Scanning %s block %d, start %d, end %d\n",
06885      (bb[j] == else_bb) ? "else" : ((bb[j] == then_bb) ? "then" : "test"),
06886      (int) bb[j]->index,
06887      (int) INSN_UID (BB_HEAD (bb[j])),
06888      (int) INSN_UID (BB_END (bb[j])));
06889 
06890       /* Anything live at the beginning of the block is obviously unavailable
06891          for allocation.  */
06892       EXECUTE_IF_SET_IN_REG_SET (bb[j]->global_live_at_start, 0, regno, rsi)
06893   {
06894     if (regno < FIRST_PSEUDO_REGISTER)
06895       CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
06896   }
06897 
06898       /* Loop through the insns in the block.  */
06899       for (;;)
06900   {
06901     /* Mark any new registers that are created as being unavailable for
06902              allocation.  Also see if the CC register used in nested IFs can be
06903              reallocated.  */
06904     if (INSN_P (insn))
06905       {
06906         rtx pattern;
06907         rtx set;
06908         int skip_nested_if = FALSE;
06909 
06910         for_each_rtx (&PATTERN (insn), frv_clear_registers_used,
06911           (void *)&tmp_reg->regs);
06912 
06913         pattern = PATTERN (insn);
06914         if (GET_CODE (pattern) == COND_EXEC)
06915     {
06916       rtx reg = XEXP (COND_EXEC_TEST (pattern), 0);
06917 
06918       if (reg != sub_cond_exec_reg)
06919         {
06920           sub_cond_exec_reg = reg;
06921           frv_ifcvt.num_nested_cond_exec++;
06922         }
06923     }
06924 
06925         set = single_set_pattern (pattern);
06926         if (set)
06927     {
06928       rtx dest = SET_DEST (set);
06929       rtx src = SET_SRC (set);
06930 
06931       if (GET_CODE (dest) == REG)
06932         {
06933           int regno = REGNO (dest);
06934           enum rtx_code src_code = GET_CODE (src);
06935 
06936           if (CC_P (regno) && src_code == COMPARE)
06937       skip_nested_if = TRUE;
06938 
06939           else if (CR_P (regno)
06940              && (src_code == IF_THEN_ELSE
06941            || COMPARISON_P (src)))
06942       skip_nested_if = TRUE;
06943         }
06944     }
06945 
06946         if (! skip_nested_if)
06947     for_each_rtx (&PATTERN (insn), frv_clear_registers_used,
06948             (void *)&frv_ifcvt.nested_cc_ok_rewrite);
06949       }
06950 
06951     if (insn == last_insn)
06952       break;
06953 
06954     insn = NEXT_INSN (insn);
06955   }
06956     }
06957 
06958   /* If this is a nested if, rewrite the CC registers that are available to
06959      include the ones that can be rewritten, to increase the chance of being
06960      able to allocate a paired CC/CR register combination.  */
06961   if (ce_info->pass > 1)
06962     {
06963       for (j = CC_FIRST; j <= CC_LAST; j++)
06964   if (TEST_HARD_REG_BIT (frv_ifcvt.nested_cc_ok_rewrite, j))
06965     SET_HARD_REG_BIT (tmp_reg->regs, j);
06966   else
06967     CLEAR_HARD_REG_BIT (tmp_reg->regs, j);
06968     }
06969 
06970   if (dump_file)
06971     {
06972       int num_gprs = 0;
06973       fprintf (dump_file, "Available GPRs: ");
06974 
06975       for (j = GPR_FIRST; j <= GPR_LAST; j++)
06976   if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
06977     {
06978       fprintf (dump_file, " %d [%s]", j, reg_names[j]);
06979       if (++num_gprs > GPR_TEMP_NUM+2)
06980         break;
06981     }
06982 
06983       fprintf (dump_file, "%s\nAvailable CRs:  ",
06984          (num_gprs > GPR_TEMP_NUM+2) ? " ..." : "");
06985 
06986       for (j = CR_FIRST; j <= CR_LAST; j++)
06987   if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
06988     fprintf (dump_file, " %d [%s]", j, reg_names[j]);
06989 
06990       fputs ("\n", dump_file);
06991 
06992       if (ce_info->pass > 1)
06993   {
06994     fprintf (dump_file, "Modifiable CCs: ");
06995     for (j = CC_FIRST; j <= CC_LAST; j++)
06996       if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
06997         fprintf (dump_file, " %d [%s]", j, reg_names[j]);
06998 
06999     fprintf (dump_file, "\n%d nested COND_EXEC statements\n",
07000        frv_ifcvt.num_nested_cond_exec);
07001   }
07002     }
07003 
07004   /* Allocate the appropriate temporary condition code register.  Try to
07005      allocate the ICR/FCR register that corresponds to the ICC/FCC register so
07006      that conditional cmp's can be done.  */
07007   if (mode == CCmode || mode == CC_UNSmode || mode == CC_NZmode)
07008     {
07009       cr_class = ICR_REGS;
07010       cc_class = ICC_REGS;
07011       cc_first = ICC_FIRST;
07012       cc_last = ICC_LAST;
07013     }
07014   else if (mode == CC_FPmode)
07015     {
07016       cr_class = FCR_REGS;
07017       cc_class = FCC_REGS;
07018       cc_first = FCC_FIRST;
07019       cc_last = FCC_LAST;
07020     }
07021   else
07022     {
07023       cc_first = cc_last = 0;
07024       cr_class = cc_class = NO_REGS;
07025     }
07026 
07027   cc = XEXP (true_expr, 0);
07028   nested_cc = cr = NULL_RTX;
07029   if (cc_class != NO_REGS)
07030     {
07031       /* For nested IFs and &&/||, see if we can find a CC and CR register pair
07032          so we can execute a csubcc/caddcc/cfcmps instruction.  */
07033       int cc_regno;
07034 
07035       for (cc_regno = cc_first; cc_regno <= cc_last; cc_regno++)
07036   {
07037     int cr_regno = cc_regno - CC_FIRST + CR_FIRST;
07038 
07039     if (TEST_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, cc_regno)
07040         && TEST_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, cr_regno))
07041       {
07042         frv_ifcvt.tmp_reg.next_reg[ (int)cr_class ] = cr_regno;
07043         cr = frv_alloc_temp_reg (tmp_reg, cr_class, CC_CCRmode, TRUE,
07044                TRUE);
07045 
07046         frv_ifcvt.tmp_reg.next_reg[ (int)cc_class ] = cc_regno;
07047         nested_cc = frv_alloc_temp_reg (tmp_reg, cc_class, CCmode,
07048               TRUE, TRUE);
07049         break;
07050       }
07051   }
07052     }
07053 
07054   if (! cr)
07055     {
07056       if (dump_file)
07057   fprintf (dump_file, "Could not allocate a CR temporary register\n");
07058 
07059       goto fail;
07060     }
07061 
07062   if (dump_file)
07063     fprintf (dump_file,
07064        "Will use %s for conditional execution, %s for nested comparisons\n",
07065        reg_names[ REGNO (cr)],
07066        (nested_cc) ? reg_names[ REGNO (nested_cc) ] : "<none>");
07067 
07068   /* Set the CCR bit.  Note for integer tests, we reverse the condition so that
07069      in an IF-THEN-ELSE sequence, we are testing the TRUE case against the CCR
07070      bit being true.  We don't do this for floating point, because of NaNs.  */
07071   code = GET_CODE (true_expr);
07072   if (GET_MODE (cc) != CC_FPmode)
07073     {
07074       code = reverse_condition (code);
07075       code_true = EQ;
07076       code_false = NE;
07077     }
07078   else
07079     {
07080       code_true = NE;
07081       code_false = EQ;
07082     }
07083 
07084   check_insn = gen_rtx_SET (VOIDmode, cr,
07085           gen_rtx_fmt_ee (code, CC_CCRmode, cc, const0_rtx));
07086 
07087   /* Record the check insn to be inserted later.  */
07088   frv_ifcvt_add_insn (check_insn, BB_END (test_bb), TRUE);
07089 
07090   /* Update the tests.  */
07091   frv_ifcvt.cr_reg = cr;
07092   frv_ifcvt.nested_cc_reg = nested_cc;
07093   *p_true = gen_rtx_fmt_ee (code_true, CC_CCRmode, cr, const0_rtx);
07094   *p_false = gen_rtx_fmt_ee (code_false, CC_CCRmode, cr, const0_rtx);
07095   return;
07096 
07097   /* Fail, don't do this conditional execution.  */
07098  fail:
07099   *p_true = NULL_RTX;
07100   *p_false = NULL_RTX;
07101   if (dump_file)
07102     fprintf (dump_file, "Disabling this conditional execution.\n");
07103 
07104   return;
07105 }
07106 
07107 
07108 /* A C expression to modify the code described by the conditional if
07109    information CE_INFO, for the basic block BB, possibly updating the tests in
07110    TRUE_EXPR, and FALSE_EXPR for converting the && and || parts of if-then or
07111    if-then-else code to conditional instructions.  Set either TRUE_EXPR or
07112    FALSE_EXPR to a null pointer if the tests cannot be converted.  */
07113 
07114 /* p_true and p_false are given expressions of the form:
07115 
07116   (and (eq:CC_CCR (reg:CC_CCR)
07117       (const_int 0))
07118        (eq:CC (reg:CC)
07119         (const_int 0))) */
07120 
07121 void
07122 frv_ifcvt_modify_multiple_tests (ce_if_block_t *ce_info,
07123                                  basic_block bb,
07124                                  rtx *p_true,
07125                                  rtx *p_false)
07126 {
07127   rtx old_true = XEXP (*p_true, 0);
07128   rtx old_false = XEXP (*p_false, 0);
07129   rtx true_expr = XEXP (*p_true, 1);
07130   rtx false_expr = XEXP (*p_false, 1);
07131   rtx test_expr;
07132   rtx old_test;
07133   rtx cr = XEXP (old_true, 0);
07134   rtx check_insn;
07135   rtx new_cr = NULL_RTX;
07136   rtx *p_new_cr = (rtx *)0;
07137   rtx if_else;
07138   rtx compare;
07139   rtx cc;
07140   enum reg_class cr_class;
07141   enum machine_mode mode = GET_MODE (true_expr);
07142   rtx (*logical_func)(rtx, rtx, rtx);
07143 
07144   if (TARGET_DEBUG_COND_EXEC)
07145     {
07146       fprintf (stderr,
07147          "\n:::::::::: frv_ifcvt_modify_multiple_tests, before modification for %s\ntrue insn:\n",
07148          ce_info->and_and_p ? "&&" : "||");
07149 
07150       debug_rtx (*p_true);
07151 
07152       fputs ("\nfalse insn:\n", stderr);
07153       debug_rtx (*p_false);
07154     }
07155 
07156   if (TARGET_NO_MULTI_CE)
07157     goto fail;
07158 
07159   if (GET_CODE (cr) != REG)
07160     goto fail;
07161 
07162   if (mode == CCmode || mode == CC_UNSmode || mode == CC_NZmode)
07163     {
07164       cr_class = ICR_REGS;
07165       p_new_cr = &frv_ifcvt.extra_int_cr;
07166     }
07167   else if (mode == CC_FPmode)
07168     {
07169       cr_class = FCR_REGS;
07170       p_new_cr = &frv_ifcvt.extra_fp_cr;
07171     }
07172   else
07173     goto fail;
07174 
07175   /* Allocate a temp CR, reusing a previously allocated temp CR if we have 3 or
07176      more &&/|| tests.  */
07177   new_cr = *p_new_cr;
07178   if (! new_cr)
07179     {
07180       new_cr = *p_new_cr = frv_alloc_temp_reg (&frv_ifcvt.tmp_reg, cr_class,
07181                  CC_CCRmode, TRUE, TRUE);
07182       if (! new_cr)
07183   goto fail;
07184     }
07185 
07186   if (ce_info->and_and_p)
07187     {
07188       old_test = old_false;
07189       test_expr = true_expr;
07190       logical_func = (GET_CODE (old_true) == EQ) ? gen_andcr : gen_andncr;
07191       *p_true = gen_rtx_NE (CC_CCRmode, cr, const0_rtx);
07192       *p_false = gen_rtx_EQ (CC_CCRmode, cr, const0_rtx);
07193     }
07194   else
07195     {
07196       old_test = old_false;
07197       test_expr = false_expr;
07198       logical_func = (GET_CODE (old_false) == EQ) ? gen_orcr : gen_orncr;
07199       *p_true = gen_rtx_EQ (CC_CCRmode, cr, const0_rtx);
07200       *p_false = gen_rtx_NE (CC_CCRmode, cr, const0_rtx);
07201     }
07202 
07203   /* First add the andcr/andncr/orcr/orncr, which will be added after the
07204      conditional check instruction, due to frv_ifcvt_add_insn being a LIFO
07205      stack.  */
07206   frv_ifcvt_add_insn ((*logical_func) (cr, cr, new_cr), BB_END (bb), TRUE);
07207 
07208   /* Now add the conditional check insn.  */
07209   cc = XEXP (test_expr, 0);
07210   compare = gen_rtx_fmt_ee (GET_CODE (test_expr), CC_CCRmode, cc, const0_rtx);
07211   if_else = gen_rtx_IF_THEN_ELSE (CC_CCRmode, old_test, compare, const0_rtx);
07212 
07213   check_insn = gen_rtx_SET (VOIDmode, new_cr, if_else);
07214 
07215   /* Add the new check insn to the list of check insns that need to be
07216      inserted.  */
07217   frv_ifcvt_add_insn (check_insn, BB_END (bb), TRUE);
07218 
07219   if (TARGET_DEBUG_COND_EXEC)
07220     {
07221       fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, after modification\ntrue insn:\n",
07222        stderr);
07223 
07224       debug_rtx (*p_true);
07225 
07226       fputs ("\nfalse insn:\n", stderr);
07227       debug_rtx (*p_false);
07228     }
07229 
07230   return;
07231 
07232  fail:
07233   *p_true = *p_false = NULL_RTX;
07234 
07235   /* If we allocated a CR register, release it.  */
07236   if (new_cr)
07237     {
07238       CLEAR_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, REGNO (new_cr));
07239       *p_new_cr = NULL_RTX;
07240     }
07241 
07242   if (TARGET_DEBUG_COND_EXEC)
07243     fputs ("\n:::::::::: frv_ifcvt_modify_multiple_tests, failed.\n", stderr);
07244 
07245   return;
07246 }
07247 
07248 
07249 /* Return a register which will be loaded with a value if an IF block is
07250    converted to conditional execution.  This is used to rewrite instructions
07251    that use constants to ones that just use registers.  */
07252 
07253 static rtx
07254 frv_ifcvt_load_value (rtx value, rtx insn ATTRIBUTE_UNUSED)
07255 {
07256   int num_alloc = frv_ifcvt.cur_scratch_regs;
07257   int i;
07258   rtx reg;
07259 
07260   /* We know gr0 == 0, so replace any errant uses.  */
07261   if (value == const0_rtx)
07262     return gen_rtx_REG (SImode, GPR_FIRST);
07263 
07264   /* First search all registers currently loaded to see if we have an
07265      applicable constant.  */
07266   if (CONSTANT_P (value)
07267       || (GET_CODE (value) == REG && REGNO (value) == LR_REGNO))
07268     {
07269       for (i = 0; i < num_alloc; i++)
07270   {
07271     if (rtx_equal_p (SET_SRC (frv_ifcvt.scratch_regs[i]), value))
07272       return SET_DEST (frv_ifcvt.scratch_regs[i]);
07273   }
07274     }
07275 
07276   /* Have we exhausted the number of registers available?  */
07277   if (num_alloc >= GPR_TEMP_NUM)
07278     {
07279       if (dump_file)
07280   fprintf (dump_file, "Too many temporary registers allocated\n");
07281 
07282       return NULL_RTX;
07283     }
07284 
07285   /* Allocate the new register.  */
07286   reg = frv_alloc_temp_reg (&frv_ifcvt.tmp_reg, GPR_REGS, SImode, TRUE, TRUE);
07287   if (! reg)
07288     {
07289       if (dump_file)
07290   fputs ("Could not find a scratch register\n", dump_file);
07291 
07292       return NULL_RTX;
07293     }
07294 
07295   frv_ifcvt.cur_scratch_regs++;
07296   frv_ifcvt.scratch_regs[num_alloc] = gen_rtx_SET (VOIDmode, reg, value);
07297 
07298   if (dump_file)
07299     {
07300       if (GET_CODE (value) == CONST_INT)
07301   fprintf (dump_file, "Register %s will hold %ld\n",
07302      reg_names[ REGNO (reg)], (long)INTVAL (value));
07303 
07304       else if (GET_CODE (value) == REG && REGNO (value) == LR_REGNO)
07305   fprintf (dump_file, "Register %s will hold LR\n",
07306      reg_names[ REGNO (reg)]);
07307 
07308       else
07309   fprintf (dump_file, "Register %s will hold a saved value\n",
07310      reg_names[ REGNO (reg)]);
07311     }
07312 
07313   return reg;
07314 }
07315 
07316 
07317 /* Update a MEM used in conditional code that might contain an offset to put
07318    the offset into a scratch register, so that the conditional load/store
07319    operations can be used.  This function returns the original pointer if the
07320    MEM is valid to use in conditional code, NULL if we can't load up the offset
07321    into a temporary register, or the new MEM if we were successful.  */
07322 
07323 static rtx