Home | History | Annotate | Line # | Download | only in nios2
      1  1.1  mrg /* Target machine subroutines for Altera Nios II.
      2  1.1  mrg    Copyright (C) 2012-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Jonah Graham (jgraham (at) altera.com),
      4  1.1  mrg    Will Reece (wreece (at) altera.com), and Jeff DaSilva (jdasilva (at) altera.com).
      5  1.1  mrg    Contributed by Mentor Graphics, Inc.
      6  1.1  mrg 
      7  1.1  mrg    This file is part of GCC.
      8  1.1  mrg 
      9  1.1  mrg    GCC is free software; you can redistribute it and/or modify it
     10  1.1  mrg    under the terms of the GNU General Public License as published
     11  1.1  mrg    by the Free Software Foundation; either version 3, or (at your
     12  1.1  mrg    option) any later version.
     13  1.1  mrg 
     14  1.1  mrg    GCC is distributed in the hope that it will be useful, but WITHOUT
     15  1.1  mrg    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16  1.1  mrg    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     17  1.1  mrg    License for more details.
     18  1.1  mrg 
     19  1.1  mrg    You should have received a copy of the GNU General Public License
     20  1.1  mrg    along with GCC; see the file COPYING3.  If not see
     21  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     22  1.1  mrg 
     23  1.1  mrg #define IN_TARGET_CODE 1
     24  1.1  mrg 
     25  1.1  mrg #include "config.h"
     26  1.1  mrg #include "system.h"
     27  1.1  mrg #include "coretypes.h"
     28  1.1  mrg #include "backend.h"
     29  1.1  mrg #include "target.h"
     30  1.1  mrg #include "rtl.h"
     31  1.1  mrg #include "tree.h"
     32  1.1  mrg #include "stringpool.h"
     33  1.1  mrg #include "attribs.h"
     34  1.1  mrg #include "df.h"
     35  1.1  mrg #include "memmodel.h"
     36  1.1  mrg #include "tm_p.h"
     37  1.1  mrg #include "optabs.h"
     38  1.1  mrg #include "regs.h"
     39  1.1  mrg #include "emit-rtl.h"
     40  1.1  mrg #include "recog.h"
     41  1.1  mrg #include "diagnostic-core.h"
     42  1.1  mrg #include "output.h"
     43  1.1  mrg #include "insn-attr.h"
     44  1.1  mrg #include "flags.h"
     45  1.1  mrg #include "explow.h"
     46  1.1  mrg #include "calls.h"
     47  1.1  mrg #include "varasm.h"
     48  1.1  mrg #include "expr.h"
     49  1.1  mrg #include "toplev.h"
     50  1.1  mrg #include "langhooks.h"
     51  1.1  mrg #include "stor-layout.h"
     52  1.1  mrg #include "builtins.h"
     53  1.1  mrg #include "tree-pass.h"
     54  1.1  mrg #include "xregex.h"
     55  1.1  mrg #include "opts.h"
     56  1.1  mrg 
     57  1.1  mrg /* This file should be included last.  */
     58  1.1  mrg #include "target-def.h"
     59  1.1  mrg 
     60  1.1  mrg /* Forward function declarations.  */
     61  1.1  mrg static bool nios2_symbolic_constant_p (rtx);
     62  1.1  mrg static bool prologue_saved_reg_p (unsigned);
     63  1.1  mrg static void nios2_load_pic_register (void);
     64  1.1  mrg static void nios2_register_custom_code (unsigned int, enum nios2_ccs_code, int);
     65  1.1  mrg static const char *nios2_unspec_reloc_name (int);
     66  1.1  mrg static void nios2_register_builtin_fndecl (unsigned, tree);
     67  1.1  mrg static rtx nios2_ldst_parallel (bool, bool, bool, rtx, int,
     68  1.1  mrg 				unsigned HOST_WIDE_INT, bool);
     69  1.1  mrg static int nios2_address_cost (rtx, machine_mode, addr_space_t, bool);
     70  1.1  mrg 
     71  1.1  mrg /* Threshold for data being put into the small data/bss area, instead
     72  1.1  mrg    of the normal data area (references to the small data/bss area take
     73  1.1  mrg    1 instruction, and use the global pointer, references to the normal
     74  1.1  mrg    data area takes 2 instructions).  */
     75  1.1  mrg unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
     76  1.1  mrg 
     77  1.1  mrg struct GTY (()) machine_function
     78  1.1  mrg {
     79  1.1  mrg   /* Current frame information, to be filled in by nios2_compute_frame_layout
     80  1.1  mrg      with register save masks, and offsets for the current function.  */
     81  1.1  mrg 
     82  1.1  mrg   /* Mask of registers to save.  */
     83  1.1  mrg   unsigned int save_mask;
     84  1.1  mrg   /* Number of bytes that the entire frame takes up.  */
     85  1.1  mrg   int total_size;
     86  1.1  mrg   /* Number of bytes that variables take up.  */
     87  1.1  mrg   int var_size;
     88  1.1  mrg   /* Number of bytes that outgoing arguments take up.  */
     89  1.1  mrg   int args_size;
     90  1.1  mrg   /* Number of bytes needed to store registers in frame.  */
     91  1.1  mrg   int save_reg_size;
     92  1.1  mrg   /* Number of bytes used to store callee-saved registers.  */
     93  1.1  mrg   int callee_save_reg_size;
     94  1.1  mrg   /* Offset from new stack pointer to store registers.  */
     95  1.1  mrg   int save_regs_offset;
     96  1.1  mrg   /* Offset from save_regs_offset to store frame pointer register.  */
     97  1.1  mrg   int fp_save_offset;
     98  1.1  mrg   /* != 0 if function has a variable argument list.  */
     99  1.1  mrg   int uses_anonymous_args;
    100  1.1  mrg   /* != 0 if frame layout already calculated.  */
    101  1.1  mrg   int initialized;
    102  1.1  mrg };
    103  1.1  mrg 
    104  1.1  mrg /* State to track the assignment of custom codes to FPU/custom builtins.  */
    105  1.1  mrg static enum nios2_ccs_code custom_code_status[256];
    106  1.1  mrg static int custom_code_index[256];
    107  1.1  mrg /* Set to true if any conflicts (re-use of a code between 0-255) are found.  */
    108  1.1  mrg static bool custom_code_conflict = false;
    109  1.1  mrg 
    110  1.1  mrg /* State for command-line options.  */
    111  1.1  mrg regex_t nios2_gprel_sec_regex;
    112  1.1  mrg regex_t nios2_r0rel_sec_regex;
    113  1.1  mrg 
    114  1.1  mrg 
    115  1.1  mrg /* Definition of builtin function types for nios2.  */
    117  1.1  mrg 
    118  1.1  mrg #define N2_FTYPES				\
    119  1.1  mrg   N2_FTYPE(1, (SF))				\
    120  1.1  mrg   N2_FTYPE(1, (VOID))				\
    121  1.1  mrg   N2_FTYPE(2, (DF, DF))				\
    122  1.1  mrg   N2_FTYPE(3, (DF, DF, DF))			\
    123  1.1  mrg   N2_FTYPE(2, (DF, SF))				\
    124  1.1  mrg   N2_FTYPE(2, (DF, SI))				\
    125  1.1  mrg   N2_FTYPE(2, (DF, UI))				\
    126  1.1  mrg   N2_FTYPE(2, (SF, DF))				\
    127  1.1  mrg   N2_FTYPE(2, (SF, SF))				\
    128  1.1  mrg   N2_FTYPE(3, (SF, SF, SF))			\
    129  1.1  mrg   N2_FTYPE(2, (SF, SI))				\
    130  1.1  mrg   N2_FTYPE(2, (SF, UI))				\
    131  1.1  mrg   N2_FTYPE(2, (SI, CVPTR))			\
    132  1.1  mrg   N2_FTYPE(2, (SI, DF))				\
    133  1.1  mrg   N2_FTYPE(3, (SI, DF, DF))			\
    134  1.1  mrg   N2_FTYPE(2, (SI, SF))				\
    135  1.1  mrg   N2_FTYPE(3, (SI, SF, SF))			\
    136  1.1  mrg   N2_FTYPE(2, (SI, SI))				\
    137  1.1  mrg   N2_FTYPE(3, (SI, SI, SI))			\
    138  1.1  mrg   N2_FTYPE(3, (SI, VPTR, SI))			\
    139  1.1  mrg   N2_FTYPE(2, (UI, CVPTR))			\
    140  1.1  mrg   N2_FTYPE(2, (UI, DF))				\
    141  1.1  mrg   N2_FTYPE(2, (UI, SF))				\
    142  1.1  mrg   N2_FTYPE(2, (VOID, DF))			\
    143  1.1  mrg   N2_FTYPE(2, (VOID, SF))			\
    144  1.1  mrg   N2_FTYPE(2, (VOID, SI))			\
    145  1.1  mrg   N2_FTYPE(3, (VOID, SI, SI))			\
    146  1.1  mrg   N2_FTYPE(2, (VOID, VPTR))			\
    147  1.1  mrg   N2_FTYPE(3, (VOID, VPTR, SI))
    148  1.1  mrg 
    149  1.1  mrg #define N2_FTYPE_OP1(R)         N2_FTYPE_ ## R ## _VOID
    150  1.1  mrg #define N2_FTYPE_OP2(R, A1)     N2_FTYPE_ ## R ## _ ## A1
    151  1.1  mrg #define N2_FTYPE_OP3(R, A1, A2) N2_FTYPE_ ## R ## _ ## A1 ## _ ## A2
    152  1.1  mrg 
    153  1.1  mrg /* Expand ftcode enumeration.  */
    154  1.1  mrg enum nios2_ftcode {
    155  1.1  mrg #define N2_FTYPE(N,ARGS) N2_FTYPE_OP ## N ARGS,
    156  1.1  mrg N2_FTYPES
    157  1.1  mrg #undef N2_FTYPE
    158  1.1  mrg N2_FTYPE_MAX
    159  1.1  mrg };
    160  1.1  mrg 
    161  1.1  mrg /* Return the tree function type, based on the ftcode.  */
    162  1.1  mrg static tree
    163  1.1  mrg nios2_ftype (enum nios2_ftcode ftcode)
    164  1.1  mrg {
    165  1.1  mrg   static tree types[(int) N2_FTYPE_MAX];
    166  1.1  mrg 
    167  1.1  mrg   tree N2_TYPE_SF = float_type_node;
    168  1.1  mrg   tree N2_TYPE_DF = double_type_node;
    169  1.1  mrg   tree N2_TYPE_SI = integer_type_node;
    170  1.1  mrg   tree N2_TYPE_UI = unsigned_type_node;
    171  1.1  mrg   tree N2_TYPE_VOID = void_type_node;
    172  1.1  mrg 
    173  1.1  mrg   static const_tree N2_TYPE_CVPTR, N2_TYPE_VPTR;
    174  1.1  mrg   if (!N2_TYPE_CVPTR)
    175  1.1  mrg     {
    176  1.1  mrg       /* const volatile void *.  */
    177  1.1  mrg       N2_TYPE_CVPTR
    178  1.1  mrg 	= build_pointer_type (build_qualified_type (void_type_node,
    179  1.1  mrg 						    (TYPE_QUAL_CONST
    180  1.1  mrg 						     | TYPE_QUAL_VOLATILE)));
    181  1.1  mrg       /* volatile void *.  */
    182  1.1  mrg       N2_TYPE_VPTR
    183  1.1  mrg 	= build_pointer_type (build_qualified_type (void_type_node,
    184  1.1  mrg 						    TYPE_QUAL_VOLATILE));
    185  1.1  mrg     }
    186  1.1  mrg   if (types[(int) ftcode] == NULL_TREE)
    187  1.1  mrg     switch (ftcode)
    188  1.1  mrg       {
    189  1.1  mrg #define N2_FTYPE_ARGS1(R) N2_TYPE_ ## R
    190  1.1  mrg #define N2_FTYPE_ARGS2(R,A1) N2_TYPE_ ## R, N2_TYPE_ ## A1
    191  1.1  mrg #define N2_FTYPE_ARGS3(R,A1,A2) N2_TYPE_ ## R, N2_TYPE_ ## A1, N2_TYPE_ ## A2
    192  1.1  mrg #define N2_FTYPE(N,ARGS)						\
    193  1.1  mrg   case N2_FTYPE_OP ## N ARGS:						\
    194  1.1  mrg     types[(int) ftcode]							\
    195  1.1  mrg       = build_function_type_list (N2_FTYPE_ARGS ## N ARGS, NULL_TREE); \
    196  1.1  mrg     break;
    197  1.1  mrg 	N2_FTYPES
    198  1.1  mrg #undef N2_FTYPE
    199  1.1  mrg       default: gcc_unreachable ();
    200  1.1  mrg       }
    201  1.1  mrg   return types[(int) ftcode];
    202  1.1  mrg }
    203  1.1  mrg 
    204  1.1  mrg 
    205  1.1  mrg /* Definition of FPU instruction descriptions.  */
    207  1.1  mrg 
    208  1.1  mrg struct nios2_fpu_insn_info
    209  1.1  mrg {
    210  1.1  mrg   const char *name;
    211  1.1  mrg   int num_operands, *optvar;
    212  1.1  mrg   int opt, no_opt;
    213  1.1  mrg #define N2F_DF            0x1
    214  1.1  mrg #define N2F_DFREQ         0x2
    215  1.1  mrg #define N2F_UNSAFE        0x4
    216  1.1  mrg #define N2F_FINITE        0x8
    217  1.1  mrg #define N2F_NO_ERRNO      0x10
    218  1.1  mrg   unsigned int flags;
    219  1.1  mrg   enum insn_code icode;
    220  1.1  mrg   enum nios2_ftcode ftcode;
    221  1.1  mrg };
    222  1.1  mrg 
    223  1.1  mrg /* Base macro for defining FPU instructions.  */
    224  1.1  mrg #define N2FPU_INSN_DEF_BASE(insn, nop, flags, icode, args)	\
    225  1.1  mrg   { #insn, nop, &nios2_custom_ ## insn, OPT_mcustom_##insn##_,	\
    226  1.1  mrg     OPT_mno_custom_##insn, flags, CODE_FOR_ ## icode,		\
    227  1.1  mrg     N2_FTYPE_OP ## nop args }
    228  1.1  mrg 
    229  1.1  mrg /* Arithmetic and math functions; 2 or 3 operand FP operations.  */
    230  1.1  mrg #define N2FPU_OP2(mode) (mode, mode)
    231  1.1  mrg #define N2FPU_OP3(mode) (mode, mode, mode)
    232  1.1  mrg #define N2FPU_INSN_DEF(code, icode, nop, flags, m, M)			\
    233  1.1  mrg   N2FPU_INSN_DEF_BASE (f ## code ## m, nop, flags,			\
    234  1.1  mrg 		       icode ## m ## f ## nop, N2FPU_OP ## nop (M ## F))
    235  1.1  mrg #define N2FPU_INSN_SF(code, nop, flags)		\
    236  1.1  mrg   N2FPU_INSN_DEF (code, code, nop, flags, s, S)
    237  1.1  mrg #define N2FPU_INSN_DF(code, nop, flags)		\
    238  1.1  mrg   N2FPU_INSN_DEF (code, code, nop, flags | N2F_DF, d, D)
    239  1.1  mrg 
    240  1.1  mrg /* Compare instructions, 3 operand FP operation with a SI result.  */
    241  1.1  mrg #define N2FPU_CMP_DEF(code, flags, m, M)				\
    242  1.1  mrg   N2FPU_INSN_DEF_BASE (fcmp ## code ## m, 3, flags,			\
    243  1.1  mrg 		       nios2_s ## code ## m ## f, (SI, M ## F, M ## F))
    244  1.1  mrg #define N2FPU_CMP_SF(code) N2FPU_CMP_DEF (code, 0, s, S)
    245  1.1  mrg #define N2FPU_CMP_DF(code) N2FPU_CMP_DEF (code, N2F_DF, d, D)
    246  1.1  mrg 
    247  1.1  mrg /* The order of definition needs to be maintained consistent with
    248  1.1  mrg    enum n2fpu_code in nios2-opts.h.  */
    249  1.1  mrg struct nios2_fpu_insn_info nios2_fpu_insn[] =
    250  1.1  mrg   {
    251  1.1  mrg     /* Single precision instructions.  */
    252  1.1  mrg     N2FPU_INSN_SF (add, 3, 0),
    253  1.1  mrg     N2FPU_INSN_SF (sub, 3, 0),
    254  1.1  mrg     N2FPU_INSN_SF (mul, 3, 0),
    255  1.1  mrg     N2FPU_INSN_SF (div, 3, 0),
    256  1.1  mrg     /* Due to textual difference between min/max and smin/smax.  */
    257  1.1  mrg     N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, s, S),
    258  1.1  mrg     N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, s, S),
    259  1.1  mrg     N2FPU_INSN_SF (neg, 2, 0),
    260  1.1  mrg     N2FPU_INSN_SF (abs, 2, 0),
    261  1.1  mrg     N2FPU_INSN_SF (sqrt, 2, 0),
    262  1.1  mrg     N2FPU_INSN_SF (sin, 2, N2F_UNSAFE),
    263  1.1  mrg     N2FPU_INSN_SF (cos, 2, N2F_UNSAFE),
    264  1.1  mrg     N2FPU_INSN_SF (tan, 2, N2F_UNSAFE),
    265  1.1  mrg     N2FPU_INSN_SF (atan, 2, N2F_UNSAFE),
    266  1.1  mrg     N2FPU_INSN_SF (exp, 2, N2F_UNSAFE),
    267  1.1  mrg     N2FPU_INSN_SF (log, 2, N2F_UNSAFE),
    268  1.1  mrg     /* Single precision compares.  */
    269  1.1  mrg     N2FPU_CMP_SF (eq), N2FPU_CMP_SF (ne),
    270  1.1  mrg     N2FPU_CMP_SF (lt), N2FPU_CMP_SF (le),
    271  1.1  mrg     N2FPU_CMP_SF (gt), N2FPU_CMP_SF (ge),
    272  1.1  mrg 
    273  1.1  mrg     /* Double precision instructions.  */
    274  1.1  mrg     N2FPU_INSN_DF (add, 3, 0),
    275  1.1  mrg     N2FPU_INSN_DF (sub, 3, 0),
    276  1.1  mrg     N2FPU_INSN_DF (mul, 3, 0),
    277  1.1  mrg     N2FPU_INSN_DF (div, 3, 0),
    278  1.1  mrg     /* Due to textual difference between min/max and smin/smax.  */
    279  1.1  mrg     N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, d, D),
    280  1.1  mrg     N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, d, D),
    281  1.1  mrg     N2FPU_INSN_DF (neg, 2, 0),
    282  1.1  mrg     N2FPU_INSN_DF (abs, 2, 0),
    283  1.1  mrg     N2FPU_INSN_DF (sqrt, 2, 0),
    284  1.1  mrg     N2FPU_INSN_DF (sin, 2, N2F_UNSAFE),
    285  1.1  mrg     N2FPU_INSN_DF (cos, 2, N2F_UNSAFE),
    286  1.1  mrg     N2FPU_INSN_DF (tan, 2, N2F_UNSAFE),
    287  1.1  mrg     N2FPU_INSN_DF (atan, 2, N2F_UNSAFE),
    288  1.1  mrg     N2FPU_INSN_DF (exp, 2, N2F_UNSAFE),
    289  1.1  mrg     N2FPU_INSN_DF (log, 2, N2F_UNSAFE),
    290  1.1  mrg     /* Double precision compares.  */
    291  1.1  mrg     N2FPU_CMP_DF (eq), N2FPU_CMP_DF (ne),
    292  1.1  mrg     N2FPU_CMP_DF (lt), N2FPU_CMP_DF (le),
    293  1.1  mrg     N2FPU_CMP_DF (gt), N2FPU_CMP_DF (ge),
    294  1.1  mrg 
    295  1.1  mrg     /* Conversion instructions.  */
    296  1.1  mrg     N2FPU_INSN_DEF_BASE (floatis,  2, 0, floatsisf2,    (SF, SI)),
    297  1.1  mrg     N2FPU_INSN_DEF_BASE (floatus,  2, 0, floatunssisf2, (SF, UI)),
    298  1.1  mrg     N2FPU_INSN_DEF_BASE (floatid,  2, 0, floatsidf2,    (DF, SI)),
    299  1.1  mrg     N2FPU_INSN_DEF_BASE (floatud,  2, 0, floatunssidf2, (DF, UI)),
    300  1.1  mrg     N2FPU_INSN_DEF_BASE (round,    2, N2F_NO_ERRNO, lroundsfsi2,   (SI, SF)),
    301  1.1  mrg     N2FPU_INSN_DEF_BASE (fixsi,    2, 0, fix_truncsfsi2,      (SI, SF)),
    302  1.1  mrg     N2FPU_INSN_DEF_BASE (fixsu,    2, 0, fixuns_truncsfsi2,   (UI, SF)),
    303  1.1  mrg     N2FPU_INSN_DEF_BASE (fixdi,    2, 0, fix_truncdfsi2,      (SI, DF)),
    304  1.1  mrg     N2FPU_INSN_DEF_BASE (fixdu,    2, 0, fixuns_truncdfsi2,   (UI, DF)),
    305  1.1  mrg     N2FPU_INSN_DEF_BASE (fextsd,   2, 0, extendsfdf2,   (DF, SF)),
    306  1.1  mrg     N2FPU_INSN_DEF_BASE (ftruncds, 2, 0, truncdfsf2,    (SF, DF)),
    307  1.1  mrg 
    308  1.1  mrg     /* X, Y access instructions.  */
    309  1.1  mrg     N2FPU_INSN_DEF_BASE (fwrx,     2, N2F_DFREQ, nios2_fwrx,   (VOID, DF)),
    310  1.1  mrg     N2FPU_INSN_DEF_BASE (fwry,     2, N2F_DFREQ, nios2_fwry,   (VOID, SF)),
    311  1.1  mrg     N2FPU_INSN_DEF_BASE (frdxlo,   1, N2F_DFREQ, nios2_frdxlo, (SF)),
    312  1.1  mrg     N2FPU_INSN_DEF_BASE (frdxhi,   1, N2F_DFREQ, nios2_frdxhi, (SF)),
    313  1.1  mrg     N2FPU_INSN_DEF_BASE (frdy,     1, N2F_DFREQ, nios2_frdy,   (SF))
    314  1.1  mrg   };
    315  1.1  mrg 
    316  1.1  mrg /* Some macros for ease of access.  */
    317  1.1  mrg #define N2FPU(code) nios2_fpu_insn[(int) code]
    318  1.1  mrg #define N2FPU_ENABLED_P(code) (N2FPU_N(code) >= 0)
    319  1.1  mrg #define N2FPU_N(code) (*N2FPU(code).optvar)
    320  1.1  mrg #define N2FPU_NAME(code) (N2FPU(code).name)
    321  1.1  mrg #define N2FPU_ICODE(code) (N2FPU(code).icode)
    322  1.1  mrg #define N2FPU_FTCODE(code) (N2FPU(code).ftcode)
    323  1.1  mrg #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE)
    324  1.1  mrg #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE)
    325  1.1  mrg #define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO)
    326  1.1  mrg #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF)
    327  1.1  mrg #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ)
    328  1.1  mrg 
    329  1.1  mrg /* Same as above, but for cases where using only the op part is shorter.  */
    330  1.1  mrg #define N2FPU_OP(op) N2FPU(n2fpu_ ## op)
    331  1.1  mrg #define N2FPU_OP_NAME(op) N2FPU_NAME(n2fpu_ ## op)
    332  1.1  mrg #define N2FPU_OP_ENABLED_P(op) N2FPU_ENABLED_P(n2fpu_ ## op)
    333  1.1  mrg 
    334  1.1  mrg /* Export the FPU insn enabled predicate to nios2.md.  */
    335  1.1  mrg bool
    336  1.1  mrg nios2_fpu_insn_enabled (enum n2fpu_code code)
    337  1.1  mrg {
    338  1.1  mrg   return N2FPU_ENABLED_P (code);
    339  1.1  mrg }
    340  1.1  mrg 
    341  1.1  mrg /* Return true if COND comparison for mode MODE is enabled under current
    342  1.1  mrg    settings.  */
    343  1.1  mrg 
    344  1.1  mrg static bool
    345  1.1  mrg nios2_fpu_compare_enabled (enum rtx_code cond, machine_mode mode)
    346  1.1  mrg {
    347  1.1  mrg   if (mode == SFmode)
    348  1.1  mrg     switch (cond)
    349  1.1  mrg       {
    350  1.1  mrg       case EQ: return N2FPU_OP_ENABLED_P (fcmpeqs);
    351  1.1  mrg       case NE: return N2FPU_OP_ENABLED_P (fcmpnes);
    352  1.1  mrg       case GT: return N2FPU_OP_ENABLED_P (fcmpgts);
    353  1.1  mrg       case GE: return N2FPU_OP_ENABLED_P (fcmpges);
    354  1.1  mrg       case LT: return N2FPU_OP_ENABLED_P (fcmplts);
    355  1.1  mrg       case LE: return N2FPU_OP_ENABLED_P (fcmples);
    356  1.1  mrg       default: break;
    357  1.1  mrg       }
    358  1.1  mrg   else if (mode == DFmode)
    359  1.1  mrg     switch (cond)
    360  1.1  mrg       {
    361  1.1  mrg       case EQ: return N2FPU_OP_ENABLED_P (fcmpeqd);
    362  1.1  mrg       case NE: return N2FPU_OP_ENABLED_P (fcmpned);
    363  1.1  mrg       case GT: return N2FPU_OP_ENABLED_P (fcmpgtd);
    364  1.1  mrg       case GE: return N2FPU_OP_ENABLED_P (fcmpged);
    365  1.1  mrg       case LT: return N2FPU_OP_ENABLED_P (fcmpltd);
    366  1.1  mrg       case LE: return N2FPU_OP_ENABLED_P (fcmpled);
    367  1.1  mrg       default: break;
    368  1.1  mrg       }
    369  1.1  mrg   return false;
    370  1.1  mrg }
    371  1.1  mrg 
    372  1.1  mrg /* Stack layout and calling conventions.  */
    373  1.1  mrg 
    374  1.1  mrg #define NIOS2_STACK_ALIGN(LOC)						\
    375  1.1  mrg   (((LOC) + ((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1))		\
    376  1.1  mrg    & ~((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1))
    377  1.1  mrg 
    378  1.1  mrg /* Return the bytes needed to compute the frame pointer from the current
    379  1.1  mrg    stack pointer.  */
    380  1.1  mrg static int
    381  1.1  mrg nios2_compute_frame_layout (void)
    382  1.1  mrg {
    383  1.1  mrg   unsigned int regno;
    384  1.1  mrg   unsigned int save_mask = 0;
    385  1.1  mrg   int total_size;
    386  1.1  mrg   int var_size;
    387  1.1  mrg   int out_args_size;
    388  1.1  mrg   int save_reg_size;
    389  1.1  mrg   int callee_save_reg_size;
    390  1.1  mrg 
    391  1.1  mrg   if (cfun->machine->initialized)
    392  1.1  mrg     return cfun->machine->total_size;
    393  1.1  mrg 
    394  1.1  mrg   /* Calculate space needed for gp registers.  */
    395  1.1  mrg   save_reg_size = 0;
    396  1.1  mrg   for (regno = 0; regno <= LAST_GP_REG; regno++)
    397  1.1  mrg     if (prologue_saved_reg_p (regno))
    398  1.1  mrg       {
    399  1.1  mrg 	save_mask |= 1 << regno;
    400  1.1  mrg 	save_reg_size += 4;
    401  1.1  mrg       }
    402  1.1  mrg 
    403  1.1  mrg   /* If we are saving any callee-save register, then assume
    404  1.1  mrg      push.n/pop.n should be used. Make sure RA is saved, and
    405  1.1  mrg      contiguous registers starting from r16-- are all saved.  */
    406  1.1  mrg   if (TARGET_HAS_CDX && save_reg_size != 0)
    407  1.1  mrg     {
    408  1.1  mrg       if ((save_mask & (1 << RA_REGNO)) == 0)
    409  1.1  mrg 	{
    410  1.1  mrg 	  save_mask |= 1 << RA_REGNO;
    411  1.1  mrg 	  save_reg_size += 4;
    412  1.1  mrg 	}
    413  1.1  mrg 
    414  1.1  mrg       for (regno = 23; regno >= 16; regno--)
    415  1.1  mrg 	if ((save_mask & (1 << regno)) != 0)
    416  1.1  mrg 	  {
    417  1.1  mrg 	    /* Starting from highest numbered callee-saved
    418  1.1  mrg 	       register that is used, make sure all regs down
    419  1.1  mrg 	       to r16 is saved, to maintain contiguous range
    420  1.1  mrg 	       for push.n/pop.n.  */
    421  1.1  mrg 	    unsigned int i;
    422  1.1  mrg 	    for (i = regno - 1; i >= 16; i--)
    423  1.1  mrg 	      if ((save_mask & (1 << i)) == 0)
    424  1.1  mrg 		{
    425  1.1  mrg 		  save_mask |= 1 << i;
    426  1.1  mrg 		  save_reg_size += 4;
    427  1.1  mrg 		}
    428  1.1  mrg 	    break;
    429  1.1  mrg 	  }
    430  1.1  mrg     }
    431  1.1  mrg 
    432  1.1  mrg   callee_save_reg_size = save_reg_size;
    433  1.1  mrg 
    434  1.1  mrg   /* If we call eh_return, we need to save the EH data registers.  */
    435  1.1  mrg   if (crtl->calls_eh_return)
    436  1.1  mrg     {
    437  1.1  mrg       unsigned i;
    438  1.1  mrg       unsigned r;
    439  1.1  mrg 
    440  1.1  mrg       for (i = 0; (r = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
    441  1.1  mrg 	if (!(save_mask & (1 << r)))
    442  1.1  mrg 	  {
    443  1.1  mrg 	    save_mask |= 1 << r;
    444  1.1  mrg 	    save_reg_size += 4;
    445  1.1  mrg 	  }
    446  1.1  mrg     }
    447  1.1  mrg 
    448  1.1  mrg   cfun->machine->fp_save_offset = 0;
    449  1.1  mrg   if (save_mask & (1 << HARD_FRAME_POINTER_REGNUM))
    450  1.1  mrg     {
    451  1.1  mrg       int fp_save_offset = 0;
    452  1.1  mrg       for (regno = 0; regno < HARD_FRAME_POINTER_REGNUM; regno++)
    453  1.1  mrg 	if (save_mask & (1 << regno))
    454  1.1  mrg 	  fp_save_offset += 4;
    455  1.1  mrg 
    456  1.1  mrg       cfun->machine->fp_save_offset = fp_save_offset;
    457  1.1  mrg     }
    458  1.1  mrg 
    459  1.1  mrg   var_size = NIOS2_STACK_ALIGN (get_frame_size ());
    460  1.1  mrg   out_args_size = NIOS2_STACK_ALIGN (crtl->outgoing_args_size);
    461  1.1  mrg   total_size = var_size + out_args_size;
    462  1.1  mrg 
    463  1.1  mrg   save_reg_size = NIOS2_STACK_ALIGN (save_reg_size);
    464  1.1  mrg   total_size += save_reg_size;
    465  1.1  mrg   total_size += NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
    466  1.1  mrg 
    467  1.1  mrg   /* Save other computed information.  */
    468  1.1  mrg   cfun->machine->save_mask = save_mask;
    469  1.1  mrg   cfun->machine->total_size = total_size;
    470  1.1  mrg   cfun->machine->var_size = var_size;
    471  1.1  mrg   cfun->machine->args_size = out_args_size;
    472  1.1  mrg   cfun->machine->save_reg_size = save_reg_size;
    473  1.1  mrg   cfun->machine->callee_save_reg_size = callee_save_reg_size;
    474  1.1  mrg   cfun->machine->initialized = reload_completed;
    475  1.1  mrg   cfun->machine->save_regs_offset = out_args_size + var_size;
    476  1.1  mrg 
    477  1.1  mrg   return total_size;
    478  1.1  mrg }
    479  1.1  mrg 
    480  1.1  mrg /* Generate save/restore of register REGNO at SP + OFFSET.  Used by the
    481  1.1  mrg    prologue/epilogue expand routines.  */
    482  1.1  mrg static void
    483  1.1  mrg save_reg (int regno, unsigned offset)
    484  1.1  mrg {
    485  1.1  mrg   rtx reg = gen_rtx_REG (SImode, regno);
    486  1.1  mrg   rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
    487  1.1  mrg   rtx_insn *insn = emit_move_insn (gen_frame_mem (Pmode, addr), reg);
    488  1.1  mrg   RTX_FRAME_RELATED_P (insn) = 1;
    489  1.1  mrg }
    490  1.1  mrg 
    491  1.1  mrg static void
    492  1.1  mrg restore_reg (int regno, unsigned offset)
    493  1.1  mrg {
    494  1.1  mrg   rtx reg = gen_rtx_REG (SImode, regno);
    495  1.1  mrg   rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
    496  1.1  mrg   rtx_insn *insn = emit_move_insn (reg, gen_frame_mem (Pmode, addr));
    497  1.1  mrg   /* Tag epilogue unwind note.  */
    498  1.1  mrg   add_reg_note (insn, REG_CFA_RESTORE, reg);
    499  1.1  mrg   RTX_FRAME_RELATED_P (insn) = 1;
    500  1.1  mrg }
    501  1.1  mrg 
    502  1.1  mrg /* This routine tests for the base register update SET in load/store
    503  1.1  mrg    multiple RTL insns, used in pop_operation_p and ldstwm_operation_p.  */
    504  1.1  mrg static bool
    505  1.1  mrg base_reg_adjustment_p (rtx set, rtx *base_reg, rtx *offset)
    506  1.1  mrg {
    507  1.1  mrg   if (GET_CODE (set) == SET
    508  1.1  mrg       && REG_P (SET_DEST (set))
    509  1.1  mrg       && GET_CODE (SET_SRC (set)) == PLUS
    510  1.1  mrg       && REG_P (XEXP (SET_SRC (set), 0))
    511  1.1  mrg       && rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
    512  1.1  mrg       && CONST_INT_P (XEXP (SET_SRC (set), 1)))
    513  1.1  mrg     {
    514  1.1  mrg       *base_reg = XEXP (SET_SRC (set), 0);
    515  1.1  mrg       *offset = XEXP (SET_SRC (set), 1);
    516  1.1  mrg       return true;
    517  1.1  mrg     }
    518  1.1  mrg   return false;
    519  1.1  mrg }
    520  1.1  mrg 
    521  1.1  mrg /* Does the CFA note work for push/pop prologue/epilogue instructions.  */
    522  1.1  mrg static void
    523  1.1  mrg nios2_create_cfa_notes (rtx_insn *insn, bool epilogue_p)
    524  1.1  mrg {
    525  1.1  mrg   int i = 0;
    526  1.1  mrg   rtx base_reg, offset, elt, pat = PATTERN (insn);
    527  1.1  mrg   if (epilogue_p)
    528  1.1  mrg     {
    529  1.1  mrg       elt = XVECEXP (pat, 0, 0);
    530  1.1  mrg       if (GET_CODE (elt) == RETURN)
    531  1.1  mrg 	i++;
    532  1.1  mrg       elt = XVECEXP (pat, 0, i);
    533  1.1  mrg       if (base_reg_adjustment_p (elt, &base_reg, &offset))
    534  1.1  mrg 	{
    535  1.1  mrg 	  add_reg_note (insn, REG_CFA_ADJUST_CFA, copy_rtx (elt));
    536  1.1  mrg 	  i++;
    537  1.1  mrg 	}
    538  1.1  mrg       for (; i < XVECLEN (pat, 0); i++)
    539  1.1  mrg 	{
    540  1.1  mrg 	  elt = SET_DEST (XVECEXP (pat, 0, i));
    541  1.1  mrg 	  gcc_assert (REG_P (elt));
    542  1.1  mrg 	  add_reg_note (insn, REG_CFA_RESTORE, elt);
    543  1.1  mrg 	}
    544  1.1  mrg     }
    545  1.1  mrg   else
    546  1.1  mrg     {
    547  1.1  mrg       /* Tag each of the prologue sets.  */
    548  1.1  mrg       for (i = 0; i < XVECLEN (pat, 0); i++)
    549  1.1  mrg 	RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
    550  1.1  mrg     }
    551  1.1  mrg }
    552  1.1  mrg 
    553  1.1  mrg /* Temp regno used inside prologue/epilogue.  */
    554  1.1  mrg #define TEMP_REG_NUM 8
    555  1.1  mrg 
    556  1.1  mrg /* Emit conditional trap for checking stack limit.  SIZE is the number of
    557  1.1  mrg    additional bytes required.
    558  1.1  mrg 
    559  1.1  mrg    GDB prologue analysis depends on this generating a direct comparison
    560  1.1  mrg    to the SP register, so the adjustment to add SIZE needs to be done on
    561  1.1  mrg    the other operand to the comparison.  Use TEMP_REG_NUM as a temporary,
    562  1.1  mrg    if necessary.  */
    563  1.1  mrg static void
    564  1.1  mrg nios2_emit_stack_limit_check (int size)
    565  1.1  mrg {
    566  1.1  mrg   rtx sum = NULL_RTX;
    567  1.1  mrg 
    568  1.1  mrg   if (GET_CODE (stack_limit_rtx) == SYMBOL_REF)
    569  1.1  mrg     {
    570  1.1  mrg       /* This generates a %hiadj/%lo pair with the constant size
    571  1.1  mrg 	 add handled by the relocations.  */
    572  1.1  mrg       sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
    573  1.1  mrg       emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size));
    574  1.1  mrg     }
    575  1.1  mrg   else if (!REG_P (stack_limit_rtx))
    576  1.1  mrg     sorry ("Unknown form for stack limit expression");
    577  1.1  mrg   else if (size == 0)
    578  1.1  mrg     sum = stack_limit_rtx;
    579  1.1  mrg   else if (SMALL_INT (size))
    580  1.1  mrg     {
    581  1.1  mrg       sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
    582  1.1  mrg       emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size));
    583  1.1  mrg     }
    584  1.1  mrg   else
    585  1.1  mrg     {
    586  1.1  mrg       sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
    587  1.1  mrg       emit_move_insn (sum, gen_int_mode (size, Pmode));
    588  1.1  mrg       emit_insn (gen_add2_insn (sum, stack_limit_rtx));
    589  1.1  mrg     }
    590  1.1  mrg 
    591  1.1  mrg   emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx, sum),
    592  1.1  mrg 			   stack_pointer_rtx, sum, GEN_INT (3)));
    593  1.1  mrg }
    594  1.1  mrg 
    595  1.1  mrg static rtx_insn *
    596  1.1  mrg nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed)
    597  1.1  mrg {
    598  1.1  mrg   rtx_insn *insn;
    599  1.1  mrg   if (SMALL_INT (immed))
    600  1.1  mrg     insn = emit_insn (gen_add2_insn (reg, gen_int_mode (immed, Pmode)));
    601  1.1  mrg   else
    602  1.1  mrg     {
    603  1.1  mrg       rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
    604  1.1  mrg       emit_move_insn (tmp, gen_int_mode (immed, Pmode));
    605  1.1  mrg       insn = emit_insn (gen_add2_insn (reg, tmp));
    606  1.1  mrg     }
    607  1.1  mrg   return insn;
    608  1.1  mrg }
    609  1.1  mrg 
    610  1.1  mrg static rtx_insn *
    611  1.1  mrg nios2_adjust_stack (int sp_adjust, bool epilogue_p)
    612  1.1  mrg {
    613  1.1  mrg   enum reg_note note_kind = REG_NOTE_MAX;
    614  1.1  mrg   rtx_insn *insn = NULL;
    615  1.1  mrg   if (sp_adjust)
    616  1.1  mrg     {
    617  1.1  mrg       if (SMALL_INT (sp_adjust))
    618  1.1  mrg 	insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
    619  1.1  mrg 					 gen_int_mode (sp_adjust, Pmode)));
    620  1.1  mrg       else
    621  1.1  mrg 	{
    622  1.1  mrg 	  rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
    623  1.1  mrg 	  emit_move_insn (tmp, gen_int_mode (sp_adjust, Pmode));
    624  1.1  mrg 	  insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
    625  1.1  mrg 	  /* Attach a note indicating what happened.  */
    626  1.1  mrg 	  if (!epilogue_p)
    627  1.1  mrg 	    note_kind = REG_FRAME_RELATED_EXPR;
    628  1.1  mrg 	}
    629  1.1  mrg       if (epilogue_p)
    630  1.1  mrg 	note_kind = REG_CFA_ADJUST_CFA;
    631  1.1  mrg       if (note_kind != REG_NOTE_MAX)
    632  1.1  mrg 	{
    633  1.1  mrg 	  rtx cfa_adj = gen_rtx_SET (stack_pointer_rtx,
    634  1.1  mrg 				     plus_constant (Pmode, stack_pointer_rtx,
    635  1.1  mrg 						    sp_adjust));
    636  1.1  mrg 	  add_reg_note (insn, note_kind, cfa_adj);
    637  1.1  mrg 	}
    638  1.1  mrg       RTX_FRAME_RELATED_P (insn) = 1;
    639  1.1  mrg     }
    640  1.1  mrg   return insn;
    641  1.1  mrg }
    642  1.1  mrg 
    643  1.1  mrg void
    644  1.1  mrg nios2_expand_prologue (void)
    645  1.1  mrg {
    646  1.1  mrg   unsigned int regno;
    647  1.1  mrg   int total_frame_size, save_offset;
    648  1.1  mrg   int sp_offset;      /* offset from base_reg to final stack value.  */
    649  1.1  mrg   int save_regs_base; /* offset from base_reg to register save area.  */
    650  1.1  mrg   rtx_insn *insn;
    651  1.1  mrg 
    652  1.1  mrg   total_frame_size = nios2_compute_frame_layout ();
    653  1.1  mrg 
    654  1.1  mrg   if (flag_stack_usage_info)
    655  1.1  mrg     current_function_static_stack_size = total_frame_size;
    656  1.1  mrg 
    657  1.1  mrg   /* When R2 CDX push.n/stwm is available, arrange for stack frame to be built
    658  1.1  mrg      using them.  */
    659  1.1  mrg   if (TARGET_HAS_CDX
    660  1.1  mrg       && (cfun->machine->save_reg_size != 0
    661  1.1  mrg 	  || cfun->machine->uses_anonymous_args))
    662  1.1  mrg     {
    663  1.1  mrg       unsigned int regmask = cfun->machine->save_mask;
    664  1.1  mrg       unsigned int callee_save_regs = regmask & 0xffff0000;
    665  1.1  mrg       unsigned int caller_save_regs = regmask & 0x0000ffff;
    666  1.1  mrg       int push_immed = 0;
    667  1.1  mrg       int pretend_args_size = NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
    668  1.1  mrg       rtx stack_mem =
    669  1.1  mrg 	gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx, -4));
    670  1.1  mrg 
    671  1.1  mrg       /* Check that there is room for the entire stack frame before doing
    672  1.1  mrg 	 any SP adjustments or pushes.  */
    673  1.1  mrg       if (crtl->limit_stack)
    674  1.1  mrg 	nios2_emit_stack_limit_check (total_frame_size);
    675  1.1  mrg 
    676  1.1  mrg       if (pretend_args_size)
    677  1.1  mrg 	{
    678  1.1  mrg 	  if (cfun->machine->uses_anonymous_args)
    679  1.1  mrg 	    {
    680  1.1  mrg 	      /* Emit a stwm to push copy of argument registers onto
    681  1.1  mrg 	         the stack for va_arg processing.  */
    682  1.1  mrg 	      unsigned int r, mask = 0, n = pretend_args_size / 4;
    683  1.1  mrg 	      for (r = LAST_ARG_REGNO - n + 1; r <= LAST_ARG_REGNO; r++)
    684  1.1  mrg 		mask |= (1 << r);
    685  1.1  mrg 	      insn = emit_insn (nios2_ldst_parallel
    686  1.1  mrg 				(false, false, false, stack_mem,
    687  1.1  mrg 				 -pretend_args_size, mask, false));
    688  1.1  mrg 	      /* Tag first SP adjustment as frame-related.  */
    689  1.1  mrg 	      RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 0)) = 1;
    690  1.1  mrg 	      RTX_FRAME_RELATED_P (insn) = 1;
    691  1.1  mrg 	    }
    692  1.1  mrg 	  else
    693  1.1  mrg 	    nios2_adjust_stack (-pretend_args_size, false);
    694  1.1  mrg 	}
    695  1.1  mrg       if (callee_save_regs)
    696  1.1  mrg 	{
    697  1.1  mrg 	  /* Emit a push.n to save registers and optionally allocate
    698  1.1  mrg 	     push_immed extra bytes on the stack.  */
    699  1.1  mrg 	  int sp_adjust;
    700  1.1  mrg 	  if (caller_save_regs)
    701  1.1  mrg 	    /* Can't allocate extra stack space yet.  */
    702  1.1  mrg 	    push_immed = 0;
    703  1.1  mrg 	  else if (cfun->machine->save_regs_offset <= 60)
    704  1.1  mrg 	    /* Stack adjustment fits entirely in the push.n.  */
    705  1.1  mrg 	    push_immed = cfun->machine->save_regs_offset;
    706  1.1  mrg 	  else if (frame_pointer_needed
    707  1.1  mrg 		   && cfun->machine->fp_save_offset == 0)
    708  1.1  mrg 	    /* Deferring the entire stack adjustment until later
    709  1.1  mrg 	       allows us to use a mov.n instead of a 32-bit addi
    710  1.1  mrg 	       instruction to set the frame pointer.  */
    711  1.1  mrg 	    push_immed = 0;
    712  1.1  mrg 	  else
    713  1.1  mrg 	    /* Splitting the stack adjustment between the push.n
    714  1.1  mrg 	       and an explicit adjustment makes it more likely that
    715  1.1  mrg 	       we can use spdeci.n for the explicit part.  */
    716  1.1  mrg 	    push_immed = 60;
    717  1.1  mrg 	  sp_adjust = -(cfun->machine->callee_save_reg_size + push_immed);
    718  1.1  mrg 	  insn = emit_insn (nios2_ldst_parallel (false, false, false,
    719  1.1  mrg 						 stack_mem, sp_adjust,
    720  1.1  mrg 						 callee_save_regs, false));
    721  1.1  mrg 	  nios2_create_cfa_notes (insn, false);
    722  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
    723  1.1  mrg 	}
    724  1.1  mrg 
    725  1.1  mrg       if (caller_save_regs)
    726  1.1  mrg 	{
    727  1.1  mrg 	  /* Emit a stwm to save the EH data regs, r4-r7.  */
    728  1.1  mrg 	  int caller_save_size = (cfun->machine->save_reg_size
    729  1.1  mrg 				  - cfun->machine->callee_save_reg_size);
    730  1.1  mrg 	  gcc_assert ((caller_save_regs & ~0xf0) == 0);
    731  1.1  mrg 	  insn = emit_insn (nios2_ldst_parallel
    732  1.1  mrg 			    (false, false, false, stack_mem,
    733  1.1  mrg 			     -caller_save_size, caller_save_regs, false));
    734  1.1  mrg 	  nios2_create_cfa_notes (insn, false);
    735  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
    736  1.1  mrg 	}
    737  1.1  mrg 
    738  1.1  mrg       save_regs_base = push_immed;
    739  1.1  mrg       sp_offset = -(cfun->machine->save_regs_offset - push_immed);
    740  1.1  mrg     }
    741  1.1  mrg   /* The non-CDX cases decrement the stack pointer, to prepare for individual
    742  1.1  mrg      register saves to the stack.  */
    743  1.1  mrg   else if (!SMALL_INT (total_frame_size))
    744  1.1  mrg     {
    745  1.1  mrg       /* We need an intermediary point, this will point at the spill block.  */
    746  1.1  mrg       nios2_adjust_stack (cfun->machine->save_regs_offset - total_frame_size,
    747  1.1  mrg 			  false);
    748  1.1  mrg       save_regs_base = 0;
    749  1.1  mrg       sp_offset = -cfun->machine->save_regs_offset;
    750  1.1  mrg       if (crtl->limit_stack)
    751  1.1  mrg 	nios2_emit_stack_limit_check (cfun->machine->save_regs_offset);
    752  1.1  mrg     }
    753  1.1  mrg   else if (total_frame_size)
    754  1.1  mrg     {
    755  1.1  mrg       nios2_adjust_stack (-total_frame_size, false);
    756  1.1  mrg       save_regs_base = cfun->machine->save_regs_offset;
    757  1.1  mrg       sp_offset = 0;
    758  1.1  mrg       if (crtl->limit_stack)
    759  1.1  mrg 	nios2_emit_stack_limit_check (0);
    760  1.1  mrg     }
    761  1.1  mrg   else
    762  1.1  mrg     save_regs_base = sp_offset = 0;
    763  1.1  mrg 
    764  1.1  mrg   /* Save the registers individually in the non-CDX case.  */
    765  1.1  mrg   if (!TARGET_HAS_CDX)
    766  1.1  mrg     {
    767  1.1  mrg       save_offset = save_regs_base + cfun->machine->save_reg_size;
    768  1.1  mrg 
    769  1.1  mrg       for (regno = LAST_GP_REG; regno > 0; regno--)
    770  1.1  mrg 	if (cfun->machine->save_mask & (1 << regno))
    771  1.1  mrg 	  {
    772  1.1  mrg 	    save_offset -= 4;
    773  1.1  mrg 	    save_reg (regno, save_offset);
    774  1.1  mrg 	  }
    775  1.1  mrg     }
    776  1.1  mrg 
    777  1.1  mrg   /* Set the hard frame pointer.  */
    778  1.1  mrg   if (frame_pointer_needed)
    779  1.1  mrg     {
    780  1.1  mrg       int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset;
    781  1.1  mrg       insn =
    782  1.1  mrg 	(fp_save_offset == 0
    783  1.1  mrg 	 ? emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)
    784  1.1  mrg 	 : emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
    785  1.1  mrg 				     stack_pointer_rtx,
    786  1.1  mrg 				     gen_int_mode (fp_save_offset, Pmode))));
    787  1.1  mrg       RTX_FRAME_RELATED_P (insn) = 1;
    788  1.1  mrg     }
    789  1.1  mrg 
    790  1.1  mrg   /* Allocate sp_offset more bytes in the stack frame.  */
    791  1.1  mrg   nios2_adjust_stack (sp_offset, false);
    792  1.1  mrg 
    793  1.1  mrg   /* Load the PIC register if needed.  */
    794  1.1  mrg   if (crtl->uses_pic_offset_table)
    795  1.1  mrg     nios2_load_pic_register ();
    796  1.1  mrg 
    797  1.1  mrg   /* If we are profiling, make sure no instructions are scheduled before
    798  1.1  mrg      the call to mcount.  */
    799  1.1  mrg   if (crtl->profile)
    800  1.1  mrg     emit_insn (gen_blockage ());
    801  1.1  mrg }
    802  1.1  mrg 
    803  1.1  mrg void
    804  1.1  mrg nios2_expand_epilogue (bool sibcall_p)
    805  1.1  mrg {
    806  1.1  mrg   rtx_insn *insn;
    807  1.1  mrg   rtx cfa_adj;
    808  1.1  mrg   int total_frame_size;
    809  1.1  mrg   int sp_adjust, save_offset;
    810  1.1  mrg   unsigned int regno;
    811  1.1  mrg 
    812  1.1  mrg   if (!sibcall_p && nios2_can_use_return_insn ())
    813  1.1  mrg     {
    814  1.1  mrg       emit_jump_insn (gen_return ());
    815  1.1  mrg       return;
    816  1.1  mrg     }
    817  1.1  mrg 
    818  1.1  mrg   emit_insn (gen_blockage ());
    819  1.1  mrg 
    820  1.1  mrg   total_frame_size = nios2_compute_frame_layout ();
    821  1.1  mrg   if (frame_pointer_needed)
    822  1.1  mrg     {
    823  1.1  mrg       /* Recover the stack pointer.  */
    824  1.1  mrg       insn =
    825  1.1  mrg 	(cfun->machine->fp_save_offset == 0
    826  1.1  mrg 	 ? emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx)
    827  1.1  mrg 	 : emit_insn (gen_add3_insn
    828  1.1  mrg 		      (stack_pointer_rtx, hard_frame_pointer_rtx,
    829  1.1  mrg 		       gen_int_mode (-cfun->machine->fp_save_offset, Pmode))));
    830  1.1  mrg       cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
    831  1.1  mrg 			       (total_frame_size
    832  1.1  mrg 				- cfun->machine->save_regs_offset));
    833  1.1  mrg       add_reg_note (insn, REG_CFA_DEF_CFA, cfa_adj);
    834  1.1  mrg       RTX_FRAME_RELATED_P (insn) = 1;
    835  1.1  mrg 
    836  1.1  mrg       save_offset = 0;
    837  1.1  mrg       sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
    838  1.1  mrg     }
    839  1.1  mrg   else if (!SMALL_INT (total_frame_size))
    840  1.1  mrg     {
    841  1.1  mrg       nios2_adjust_stack (cfun->machine->save_regs_offset, true);
    842  1.1  mrg       save_offset = 0;
    843  1.1  mrg       sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
    844  1.1  mrg     }
    845  1.1  mrg   else
    846  1.1  mrg     {
    847  1.1  mrg       save_offset = cfun->machine->save_regs_offset;
    848  1.1  mrg       sp_adjust = total_frame_size;
    849  1.1  mrg     }
    850  1.1  mrg 
    851  1.1  mrg   if (!TARGET_HAS_CDX)
    852  1.1  mrg     {
    853  1.1  mrg       /* Generate individual register restores.  */
    854  1.1  mrg       save_offset += cfun->machine->save_reg_size;
    855  1.1  mrg 
    856  1.1  mrg       for (regno = LAST_GP_REG; regno > 0; regno--)
    857  1.1  mrg 	if (cfun->machine->save_mask & (1 << regno))
    858  1.1  mrg 	  {
    859  1.1  mrg 	    save_offset -= 4;
    860  1.1  mrg 	    restore_reg (regno, save_offset);
    861  1.1  mrg 	  }
    862  1.1  mrg       nios2_adjust_stack (sp_adjust, true);
    863  1.1  mrg     }
    864  1.1  mrg   else if (cfun->machine->save_reg_size == 0)
    865  1.1  mrg     {
    866  1.1  mrg       /* Nothing to restore, just recover the stack position.  */
    867  1.1  mrg       nios2_adjust_stack (sp_adjust, true);
    868  1.1  mrg     }
    869  1.1  mrg   else
    870  1.1  mrg     {
    871  1.1  mrg       /* Emit CDX pop.n/ldwm to restore registers and optionally return.  */
    872  1.1  mrg       unsigned int regmask = cfun->machine->save_mask;
    873  1.1  mrg       unsigned int callee_save_regs = regmask & 0xffff0000;
    874  1.1  mrg       unsigned int caller_save_regs = regmask & 0x0000ffff;
    875  1.1  mrg       int callee_save_size = cfun->machine->callee_save_reg_size;
    876  1.1  mrg       int caller_save_size = cfun->machine->save_reg_size - callee_save_size;
    877  1.1  mrg       int pretend_args_size = NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
    878  1.1  mrg       bool ret_p = (!pretend_args_size && !crtl->calls_eh_return
    879  1.1  mrg 		    && !sibcall_p);
    880  1.1  mrg 
    881  1.1  mrg       if (!ret_p || caller_save_size > 0)
    882  1.1  mrg 	sp_adjust = save_offset;
    883  1.1  mrg       else
    884  1.1  mrg 	sp_adjust = (save_offset > 60 ? save_offset - 60 : 0);
    885  1.1  mrg 
    886  1.1  mrg       save_offset -= sp_adjust;
    887  1.1  mrg 
    888  1.1  mrg       nios2_adjust_stack (sp_adjust, true);
    889  1.1  mrg 
    890  1.1  mrg       if (caller_save_regs)
    891  1.1  mrg 	{
    892  1.1  mrg 	  /* Emit a ldwm to restore EH data regs.  */
    893  1.1  mrg 	  rtx stack_mem = gen_frame_mem (SImode, stack_pointer_rtx);
    894  1.1  mrg 	  insn = emit_insn (nios2_ldst_parallel
    895  1.1  mrg 			    (true, true, true, stack_mem,
    896  1.1  mrg 			     caller_save_size, caller_save_regs, false));
    897  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
    898  1.1  mrg 	  nios2_create_cfa_notes (insn, true);
    899  1.1  mrg 	}
    900  1.1  mrg 
    901  1.1  mrg       if (callee_save_regs)
    902  1.1  mrg 	{
    903  1.1  mrg 	  int sp_adjust = save_offset + callee_save_size;
    904  1.1  mrg 	  rtx stack_mem;
    905  1.1  mrg 	  if (ret_p)
    906  1.1  mrg 	    {
    907  1.1  mrg 	      /* Emit a pop.n to restore regs and return.  */
    908  1.1  mrg 	      stack_mem =
    909  1.1  mrg 		gen_frame_mem (SImode,
    910  1.1  mrg 			       gen_rtx_PLUS (Pmode, stack_pointer_rtx,
    911  1.1  mrg 					     gen_int_mode (sp_adjust - 4,
    912  1.1  mrg 							   Pmode)));
    913  1.1  mrg 	      insn =
    914  1.1  mrg 		emit_jump_insn (nios2_ldst_parallel (true, false, false,
    915  1.1  mrg 						     stack_mem, sp_adjust,
    916  1.1  mrg 						     callee_save_regs, ret_p));
    917  1.1  mrg 	      RTX_FRAME_RELATED_P (insn) = 1;
    918  1.1  mrg 	      /* No need to attach CFA notes since we cannot step over
    919  1.1  mrg 		 a return.  */
    920  1.1  mrg 	      return;
    921  1.1  mrg 	    }
    922  1.1  mrg 	  else
    923  1.1  mrg 	    {
    924  1.1  mrg 	      /* If no return, we have to use the ldwm form.  */
    925  1.1  mrg 	      stack_mem = gen_frame_mem (SImode, stack_pointer_rtx);
    926  1.1  mrg 	      insn =
    927  1.1  mrg 		emit_insn (nios2_ldst_parallel (true, true, true,
    928  1.1  mrg 						stack_mem, sp_adjust,
    929  1.1  mrg 						callee_save_regs, ret_p));
    930  1.1  mrg 	      RTX_FRAME_RELATED_P (insn) = 1;
    931  1.1  mrg 	      nios2_create_cfa_notes (insn, true);
    932  1.1  mrg 	    }
    933  1.1  mrg 	}
    934  1.1  mrg 
    935  1.1  mrg       if (pretend_args_size)
    936  1.1  mrg 	nios2_adjust_stack (pretend_args_size, true);
    937  1.1  mrg     }
    938  1.1  mrg 
    939  1.1  mrg   /* Add in the __builtin_eh_return stack adjustment.  */
    940  1.1  mrg   if (crtl->calls_eh_return)
    941  1.1  mrg     emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));
    942  1.1  mrg 
    943  1.1  mrg   if (!sibcall_p)
    944  1.1  mrg     emit_jump_insn (gen_simple_return ());
    945  1.1  mrg }
    946  1.1  mrg 
    947  1.1  mrg bool
    948  1.1  mrg nios2_expand_return (void)
    949  1.1  mrg {
    950  1.1  mrg   /* If CDX is available, generate a pop.n instruction to do both
    951  1.1  mrg      the stack pop and return.  */
    952  1.1  mrg   if (TARGET_HAS_CDX)
    953  1.1  mrg     {
    954  1.1  mrg       int total_frame_size = nios2_compute_frame_layout ();
    955  1.1  mrg       int sp_adjust = (cfun->machine->save_regs_offset
    956  1.1  mrg 		       + cfun->machine->callee_save_reg_size);
    957  1.1  mrg       gcc_assert (sp_adjust == total_frame_size);
    958  1.1  mrg       if (sp_adjust != 0)
    959  1.1  mrg 	{
    960  1.1  mrg 	  rtx mem =
    961  1.1  mrg 	    gen_frame_mem (SImode,
    962  1.1  mrg 			   plus_constant (Pmode, stack_pointer_rtx,
    963  1.1  mrg 					  sp_adjust - 4, false));
    964  1.1  mrg 	  rtx_insn *insn =
    965  1.1  mrg 	    emit_jump_insn (nios2_ldst_parallel (true, false, false,
    966  1.1  mrg 						 mem, sp_adjust,
    967  1.1  mrg 						 cfun->machine->save_mask,
    968  1.1  mrg 						 true));
    969  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
    970  1.1  mrg 	  /* No need to create CFA notes since we can't step over
    971  1.1  mrg 	     a return.  */
    972  1.1  mrg 	  return true;
    973  1.1  mrg 	}
    974  1.1  mrg     }
    975  1.1  mrg   return false;
    976  1.1  mrg }
    977  1.1  mrg 
    978  1.1  mrg /* Implement RETURN_ADDR_RTX.  Note, we do not support moving
    979  1.1  mrg    back to a previous frame.  */
    980  1.1  mrg rtx
    981  1.1  mrg nios2_get_return_address (int count)
    982  1.1  mrg {
    983  1.1  mrg   if (count != 0)
    984  1.1  mrg     return const0_rtx;
    985  1.1  mrg 
    986  1.1  mrg   return get_hard_reg_initial_val (Pmode, RA_REGNO);
    987  1.1  mrg }
    988  1.1  mrg 
    989  1.1  mrg /* Emit code to change the current function's return address to
    990  1.1  mrg    ADDRESS.  SCRATCH is available as a scratch register, if needed.
    991  1.1  mrg    ADDRESS and SCRATCH are both word-mode GPRs.  */
    992  1.1  mrg void
    993  1.1  mrg nios2_set_return_address (rtx address, rtx scratch)
    994  1.1  mrg {
    995  1.1  mrg   nios2_compute_frame_layout ();
    996  1.1  mrg   if (cfun->machine->save_mask & (1 << RA_REGNO))
    997  1.1  mrg     {
    998  1.1  mrg       unsigned offset = cfun->machine->save_reg_size - 4;
    999  1.1  mrg       rtx base;
   1000  1.1  mrg 
   1001  1.1  mrg       if (frame_pointer_needed)
   1002  1.1  mrg 	base = hard_frame_pointer_rtx;
   1003  1.1  mrg       else
   1004  1.1  mrg 	{
   1005  1.1  mrg 	  base = stack_pointer_rtx;
   1006  1.1  mrg 	  offset += cfun->machine->save_regs_offset;
   1007  1.1  mrg 
   1008  1.1  mrg 	  if (!SMALL_INT (offset))
   1009  1.1  mrg 	    {
   1010  1.1  mrg 	      emit_move_insn (scratch, gen_int_mode (offset, Pmode));
   1011  1.1  mrg 	      emit_insn (gen_add2_insn (scratch, base));
   1012  1.1  mrg 	      base = scratch;
   1013  1.1  mrg 	      offset = 0;
   1014  1.1  mrg 	    }
   1015  1.1  mrg 	}
   1016  1.1  mrg       if (offset)
   1017  1.1  mrg 	base = plus_constant (Pmode, base, offset);
   1018  1.1  mrg       emit_move_insn (gen_rtx_MEM (Pmode, base), address);
   1019  1.1  mrg     }
   1020  1.1  mrg   else
   1021  1.1  mrg     emit_move_insn (gen_rtx_REG (Pmode, RA_REGNO), address);
   1022  1.1  mrg }
   1023  1.1  mrg 
   1024  1.1  mrg /* Implement FUNCTION_PROFILER macro.  */
   1025  1.1  mrg void
   1026  1.1  mrg nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
   1027  1.1  mrg {
   1028  1.1  mrg   fprintf (file, "\tmov\tr8, ra\n");
   1029  1.1  mrg   if (flag_pic == 1)
   1030  1.1  mrg     {
   1031  1.1  mrg       fprintf (file, "\tnextpc\tr2\n");
   1032  1.1  mrg       fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
   1033  1.1  mrg       fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
   1034  1.1  mrg       fprintf (file, "\tadd\tr2, r2, r3\n");
   1035  1.1  mrg       fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n");
   1036  1.1  mrg       fprintf (file, "\tcallr\tr2\n");
   1037  1.1  mrg     }
   1038  1.1  mrg   else if (flag_pic == 2)
   1039  1.1  mrg     {
   1040  1.1  mrg       fprintf (file, "\tnextpc\tr2\n");
   1041  1.1  mrg       fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
   1042  1.1  mrg       fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
   1043  1.1  mrg       fprintf (file, "\tadd\tr2, r2, r3\n");
   1044  1.1  mrg       fprintf (file, "\tmovhi\tr3, %%call_hiadj(_mcount)\n");
   1045  1.1  mrg       fprintf (file, "\taddi\tr3, r3, %%call_lo(_mcount)\n");
   1046  1.1  mrg       fprintf (file, "\tadd\tr3, r2, r3\n");
   1047  1.1  mrg       fprintf (file, "\tldw\tr2, 0(r3)\n");
   1048  1.1  mrg       fprintf (file, "\tcallr\tr2\n");
   1049  1.1  mrg     }
   1050  1.1  mrg   else
   1051  1.1  mrg     fprintf (file, "\tcall\t_mcount\n");
   1052  1.1  mrg   fprintf (file, "\tmov\tra, r8\n");
   1053  1.1  mrg }
   1054  1.1  mrg 
   1055  1.1  mrg /* Dump stack layout.  */
   1056  1.1  mrg static void
   1057  1.1  mrg nios2_dump_frame_layout (FILE *file)
   1058  1.1  mrg {
   1059  1.1  mrg   fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
   1060  1.1  mrg   fprintf (file, "\t%s total_size = %d\n", ASM_COMMENT_START,
   1061  1.1  mrg            cfun->machine->total_size);
   1062  1.1  mrg   fprintf (file, "\t%s var_size = %d\n", ASM_COMMENT_START,
   1063  1.1  mrg            cfun->machine->var_size);
   1064  1.1  mrg   fprintf (file, "\t%s args_size = %d\n", ASM_COMMENT_START,
   1065  1.1  mrg            cfun->machine->args_size);
   1066  1.1  mrg   fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
   1067  1.1  mrg            cfun->machine->save_reg_size);
   1068  1.1  mrg   fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
   1069  1.1  mrg            cfun->machine->initialized);
   1070  1.1  mrg   fprintf (file, "\t%s save_regs_offset = %d\n", ASM_COMMENT_START,
   1071  1.1  mrg            cfun->machine->save_regs_offset);
   1072  1.1  mrg   fprintf (file, "\t%s is_leaf = %d\n", ASM_COMMENT_START,
   1073  1.1  mrg            crtl->is_leaf);
   1074  1.1  mrg   fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
   1075  1.1  mrg            frame_pointer_needed);
   1076  1.1  mrg   fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
   1077  1.1  mrg            crtl->args.pretend_args_size);
   1078  1.1  mrg }
   1079  1.1  mrg 
   1080  1.1  mrg /* Return true if REGNO should be saved in the prologue.  */
   1081  1.1  mrg static bool
   1082  1.1  mrg prologue_saved_reg_p (unsigned regno)
   1083  1.1  mrg {
   1084  1.1  mrg   gcc_assert (GP_REG_P (regno));
   1085  1.1  mrg 
   1086  1.1  mrg   if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
   1087  1.1  mrg     return true;
   1088  1.1  mrg 
   1089  1.1  mrg   if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
   1090  1.1  mrg     return true;
   1091  1.1  mrg 
   1092  1.1  mrg   if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
   1093  1.1  mrg     return true;
   1094  1.1  mrg 
   1095  1.1  mrg   if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO))
   1096  1.1  mrg     return true;
   1097  1.1  mrg 
   1098  1.1  mrg   return false;
   1099  1.1  mrg }
   1100  1.1  mrg 
   1101  1.1  mrg /* Implement TARGET_CAN_ELIMINATE.  */
   1102  1.1  mrg static bool
   1103  1.1  mrg nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
   1104  1.1  mrg {
   1105  1.1  mrg   if (to == STACK_POINTER_REGNUM)
   1106  1.1  mrg     return !frame_pointer_needed;
   1107  1.1  mrg   return true;
   1108  1.1  mrg }
   1109  1.1  mrg 
   1110  1.1  mrg /* Implement INITIAL_ELIMINATION_OFFSET macro.  */
   1111  1.1  mrg int
   1112  1.1  mrg nios2_initial_elimination_offset (int from, int to)
   1113  1.1  mrg {
   1114  1.1  mrg   int offset;
   1115  1.1  mrg 
   1116  1.1  mrg   nios2_compute_frame_layout ();
   1117  1.1  mrg 
   1118  1.1  mrg   /* Set OFFSET to the offset from the stack pointer.  */
   1119  1.1  mrg   switch (from)
   1120  1.1  mrg     {
   1121  1.1  mrg     case FRAME_POINTER_REGNUM:
   1122  1.1  mrg       /* This is the high end of the local variable storage, not the
   1123  1.1  mrg 	 hard frame pointer.  */
   1124  1.1  mrg       offset = cfun->machine->args_size + cfun->machine->var_size;
   1125  1.1  mrg       break;
   1126  1.1  mrg 
   1127  1.1  mrg     case ARG_POINTER_REGNUM:
   1128  1.1  mrg       offset = cfun->machine->total_size;
   1129  1.1  mrg       offset -= crtl->args.pretend_args_size;
   1130  1.1  mrg       break;
   1131  1.1  mrg 
   1132  1.1  mrg     default:
   1133  1.1  mrg       gcc_unreachable ();
   1134  1.1  mrg     }
   1135  1.1  mrg 
   1136  1.1  mrg     /* If we are asked for the frame pointer offset, then adjust OFFSET
   1137  1.1  mrg        by the offset from the frame pointer to the stack pointer.  */
   1138  1.1  mrg   if (to == HARD_FRAME_POINTER_REGNUM)
   1139  1.1  mrg     offset -= (cfun->machine->save_regs_offset
   1140  1.1  mrg 	       + cfun->machine->fp_save_offset);
   1141  1.1  mrg 
   1142  1.1  mrg   return offset;
   1143  1.1  mrg }
   1144  1.1  mrg 
   1145  1.1  mrg /* Return nonzero if this function is known to have a null epilogue.
   1146  1.1  mrg    This allows the optimizer to omit jumps to jumps if no stack
   1147  1.1  mrg    was created.  */
   1148  1.1  mrg int
   1149  1.1  mrg nios2_can_use_return_insn (void)
   1150  1.1  mrg {
   1151  1.1  mrg   int total_frame_size;
   1152  1.1  mrg 
   1153  1.1  mrg   if (!reload_completed || crtl->profile)
   1154  1.1  mrg     return 0;
   1155  1.1  mrg 
   1156  1.1  mrg   total_frame_size = nios2_compute_frame_layout ();
   1157  1.1  mrg 
   1158  1.1  mrg   /* If CDX is available, check if we can return using a
   1159  1.1  mrg      single pop.n instruction.  */
   1160  1.1  mrg   if (TARGET_HAS_CDX
   1161  1.1  mrg       && !frame_pointer_needed
   1162  1.1  mrg       && cfun->machine->save_regs_offset <= 60
   1163  1.1  mrg       && (cfun->machine->save_mask & 0x80000000) != 0
   1164  1.1  mrg       && (cfun->machine->save_mask & 0xffff) == 0
   1165  1.1  mrg       && crtl->args.pretend_args_size == 0)
   1166  1.1  mrg     return true;
   1167  1.1  mrg 
   1168  1.1  mrg   return total_frame_size == 0;
   1169  1.1  mrg }
   1170  1.1  mrg 
   1171  1.1  mrg 
   1172  1.1  mrg /* Check and signal some warnings/errors on FPU insn options.  */
   1174  1.1  mrg static void
   1175  1.1  mrg nios2_custom_check_insns (void)
   1176  1.1  mrg {
   1177  1.1  mrg   unsigned int i, j;
   1178  1.1  mrg   bool errors = false;
   1179  1.1  mrg 
   1180  1.1  mrg   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   1181  1.1  mrg     if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i))
   1182  1.1  mrg       {
   1183  1.1  mrg 	for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++)
   1184  1.1  mrg 	  if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j))
   1185  1.1  mrg 	    {
   1186  1.1  mrg 	      error ("switch %<-mcustom-%s%> is required for "
   1187  1.1  mrg 		     "double-precision floating-point", N2FPU_NAME (j));
   1188  1.1  mrg 	      errors = true;
   1189  1.1  mrg 	    }
   1190  1.1  mrg 	break;
   1191  1.1  mrg       }
   1192  1.1  mrg 
   1193  1.1  mrg   if (errors || custom_code_conflict)
   1194  1.1  mrg     fatal_error (input_location,
   1195  1.1  mrg 		 "conflicting use of %<-mcustom%> switches, "
   1196  1.1  mrg 		 "target attributes, "
   1197  1.1  mrg 		 "and/or %<__builtin_custom_%> functions");
   1198  1.1  mrg }
   1199  1.1  mrg 
   1200  1.1  mrg static void
   1201  1.1  mrg nios2_set_fpu_custom_code (enum n2fpu_code code, int n, bool override_p)
   1202  1.1  mrg {
   1203  1.1  mrg   if (override_p || N2FPU_N (code) == -1)
   1204  1.1  mrg     N2FPU_N (code) = n;
   1205  1.1  mrg   nios2_register_custom_code (n, CCS_FPU, (int) code);
   1206  1.1  mrg }
   1207  1.1  mrg 
   1208  1.1  mrg /* Type to represent a standard FPU config.  */
   1209  1.1  mrg struct nios2_fpu_config
   1210  1.1  mrg {
   1211  1.1  mrg   const char *name;
   1212  1.1  mrg   bool set_sp_constants;
   1213  1.1  mrg   int code[n2fpu_code_num];
   1214  1.1  mrg };
   1215  1.1  mrg 
   1216  1.1  mrg #define NIOS2_FPU_CONFIG_NUM 4
   1217  1.1  mrg static struct nios2_fpu_config custom_fpu_config[NIOS2_FPU_CONFIG_NUM];
   1218  1.1  mrg 
   1219  1.1  mrg static void
   1220  1.1  mrg nios2_init_fpu_configs (void)
   1221  1.1  mrg {
   1222  1.1  mrg   struct nios2_fpu_config* cfg;
   1223  1.1  mrg   int i = 0;
   1224  1.1  mrg #define NEXT_FPU_CONFIG				\
   1225  1.1  mrg   do {						\
   1226  1.1  mrg     cfg = &custom_fpu_config[i++];			\
   1227  1.1  mrg     memset (cfg, -1, sizeof (struct nios2_fpu_config));\
   1228  1.1  mrg   } while (0)
   1229  1.1  mrg 
   1230  1.1  mrg   NEXT_FPU_CONFIG;
   1231  1.1  mrg   cfg->name = "60-1";
   1232  1.1  mrg   cfg->set_sp_constants  = true;
   1233  1.1  mrg   cfg->code[n2fpu_fmuls] = 252;
   1234  1.1  mrg   cfg->code[n2fpu_fadds] = 253;
   1235  1.1  mrg   cfg->code[n2fpu_fsubs] = 254;
   1236  1.1  mrg 
   1237  1.1  mrg   NEXT_FPU_CONFIG;
   1238  1.1  mrg   cfg->name = "60-2";
   1239  1.1  mrg   cfg->set_sp_constants  = true;
   1240  1.1  mrg   cfg->code[n2fpu_fmuls] = 252;
   1241  1.1  mrg   cfg->code[n2fpu_fadds] = 253;
   1242  1.1  mrg   cfg->code[n2fpu_fsubs] = 254;
   1243  1.1  mrg   cfg->code[n2fpu_fdivs] = 255;
   1244  1.1  mrg 
   1245  1.1  mrg   NEXT_FPU_CONFIG;
   1246  1.1  mrg   cfg->name = "72-3";
   1247  1.1  mrg   cfg->set_sp_constants    = true;
   1248  1.1  mrg   cfg->code[n2fpu_floatus] = 243;
   1249  1.1  mrg   cfg->code[n2fpu_fixsi]   = 244;
   1250  1.1  mrg   cfg->code[n2fpu_floatis] = 245;
   1251  1.1  mrg   cfg->code[n2fpu_fcmpgts] = 246;
   1252  1.1  mrg   cfg->code[n2fpu_fcmples] = 249;
   1253  1.1  mrg   cfg->code[n2fpu_fcmpeqs] = 250;
   1254  1.1  mrg   cfg->code[n2fpu_fcmpnes] = 251;
   1255  1.1  mrg   cfg->code[n2fpu_fmuls]   = 252;
   1256  1.1  mrg   cfg->code[n2fpu_fadds]   = 253;
   1257  1.1  mrg   cfg->code[n2fpu_fsubs]   = 254;
   1258  1.1  mrg   cfg->code[n2fpu_fdivs]   = 255;
   1259  1.1  mrg 
   1260  1.1  mrg   NEXT_FPU_CONFIG;
   1261  1.1  mrg   cfg->name = "fph2";
   1262  1.1  mrg   cfg->code[n2fpu_fabss]   = 224;
   1263  1.1  mrg   cfg->code[n2fpu_fnegs]   = 225;
   1264  1.1  mrg   cfg->code[n2fpu_fcmpnes] = 226;
   1265  1.1  mrg   cfg->code[n2fpu_fcmpeqs] = 227;
   1266  1.1  mrg   cfg->code[n2fpu_fcmpges] = 228;
   1267  1.1  mrg   cfg->code[n2fpu_fcmpgts] = 229;
   1268  1.1  mrg   cfg->code[n2fpu_fcmples] = 230;
   1269  1.1  mrg   cfg->code[n2fpu_fcmplts] = 231;
   1270  1.1  mrg   cfg->code[n2fpu_fmaxs]   = 232;
   1271  1.1  mrg   cfg->code[n2fpu_fmins]   = 233;
   1272  1.1  mrg   cfg->code[n2fpu_round]   = 248;
   1273  1.1  mrg   cfg->code[n2fpu_fixsi]   = 249;
   1274  1.1  mrg   cfg->code[n2fpu_floatis] = 250;
   1275  1.1  mrg   cfg->code[n2fpu_fsqrts]  = 251;
   1276  1.1  mrg   cfg->code[n2fpu_fmuls]   = 252;
   1277  1.1  mrg   cfg->code[n2fpu_fadds]   = 253;
   1278  1.1  mrg   cfg->code[n2fpu_fsubs]   = 254;
   1279  1.1  mrg   cfg->code[n2fpu_fdivs]   = 255;
   1280  1.1  mrg 
   1281  1.1  mrg #undef NEXT_FPU_CONFIG
   1282  1.1  mrg   gcc_assert (i == NIOS2_FPU_CONFIG_NUM);
   1283  1.1  mrg }
   1284  1.1  mrg 
   1285  1.1  mrg static struct nios2_fpu_config *
   1286  1.1  mrg nios2_match_custom_fpu_cfg (const char *cfgname, const char *endp)
   1287  1.1  mrg {
   1288  1.1  mrg   int i;
   1289  1.1  mrg   for (i = 0; i < NIOS2_FPU_CONFIG_NUM; i++)
   1290  1.1  mrg     {
   1291  1.1  mrg       bool match = !(endp != NULL
   1292  1.1  mrg 		     ? strncmp (custom_fpu_config[i].name, cfgname,
   1293  1.1  mrg 				endp - cfgname)
   1294  1.1  mrg 		     : strcmp (custom_fpu_config[i].name, cfgname));
   1295  1.1  mrg       if (match)
   1296  1.1  mrg 	return &custom_fpu_config[i];
   1297  1.1  mrg     }
   1298  1.1  mrg   return NULL;
   1299  1.1  mrg }
   1300  1.1  mrg 
   1301  1.1  mrg /* Use CFGNAME to lookup FPU config, ENDP if not NULL marks end of string.
   1302  1.1  mrg    OVERRIDE is true if loaded config codes should overwrite current state.  */
   1303  1.1  mrg static void
   1304  1.1  mrg nios2_handle_custom_fpu_cfg (const char *cfgname, const char *endp,
   1305  1.1  mrg 			     bool override)
   1306  1.1  mrg {
   1307  1.1  mrg   struct nios2_fpu_config *cfg = nios2_match_custom_fpu_cfg (cfgname, endp);
   1308  1.1  mrg   if (cfg)
   1309  1.1  mrg     {
   1310  1.1  mrg       unsigned int i;
   1311  1.1  mrg       for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   1312  1.1  mrg 	if (cfg->code[i] >= 0)
   1313  1.1  mrg 	  nios2_set_fpu_custom_code ((enum n2fpu_code) i, cfg->code[i],
   1314  1.1  mrg 				     override);
   1315  1.1  mrg       if (cfg->set_sp_constants)
   1316  1.1  mrg 	flag_single_precision_constant = 1;
   1317  1.1  mrg     }
   1318  1.1  mrg   else
   1319  1.1  mrg     warning (0, "ignoring unrecognized switch %<-mcustom-fpu-cfg%> "
   1320  1.1  mrg 	     "value %<%s%>", cfgname);
   1321  1.1  mrg 
   1322  1.1  mrg   /* Guard against errors in the standard configurations.  */
   1323  1.1  mrg   nios2_custom_check_insns ();
   1324  1.1  mrg }
   1325  1.1  mrg 
   1326  1.1  mrg /* Check individual FPU insn options, and register custom code.  */
   1327  1.1  mrg static void
   1328  1.1  mrg nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
   1329  1.1  mrg {
   1330  1.1  mrg   int param = N2FPU_N (fpu_insn_index);
   1331  1.1  mrg 
   1332  1.1  mrg   if (param >= 0 && param <= 255)
   1333  1.1  mrg     nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
   1334  1.1  mrg 
   1335  1.1  mrg   /* Valid values are 0-255, but also allow -1 so that the
   1336  1.1  mrg      -mno-custom-<opt> switches work.  */
   1337  1.1  mrg   else if (param != -1)
   1338  1.1  mrg     error ("switch %<-mcustom-%s%> value %d must be between 0 and 255",
   1339  1.1  mrg 	   N2FPU_NAME (fpu_insn_index), param);
   1340  1.1  mrg }
   1341  1.1  mrg 
   1342  1.1  mrg /* Allocate a chunk of memory for per-function machine-dependent data.  */
   1343  1.1  mrg static struct machine_function *
   1344  1.1  mrg nios2_init_machine_status (void)
   1345  1.1  mrg {
   1346  1.1  mrg   return ggc_cleared_alloc<machine_function> ();
   1347  1.1  mrg }
   1348  1.1  mrg 
   1349  1.1  mrg /* Implement TARGET_OPTION_OVERRIDE.  */
   1350  1.1  mrg static void
   1351  1.1  mrg nios2_option_override (void)
   1352  1.1  mrg {
   1353  1.1  mrg   unsigned int i;
   1354  1.1  mrg 
   1355  1.1  mrg #ifdef SUBTARGET_OVERRIDE_OPTIONS
   1356  1.1  mrg   SUBTARGET_OVERRIDE_OPTIONS;
   1357  1.1  mrg #endif
   1358  1.1  mrg 
   1359  1.1  mrg   /* Check for unsupported options.  */
   1360  1.1  mrg   if (flag_pic && !TARGET_LINUX_ABI)
   1361  1.1  mrg     sorry ("position-independent code requires the Linux ABI");
   1362  1.1  mrg   if (flag_pic && stack_limit_rtx
   1363  1.1  mrg       && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
   1364  1.1  mrg     sorry ("PIC support for %<-fstack-limit-symbol%>");
   1365  1.1  mrg 
   1366  1.1  mrg   /* Function to allocate machine-dependent function status.  */
   1367  1.1  mrg   init_machine_status = &nios2_init_machine_status;
   1368  1.1  mrg 
   1369  1.1  mrg   nios2_section_threshold
   1370  1.1  mrg     = (OPTION_SET_P (g_switch_value)
   1371  1.1  mrg        ? g_switch_value : NIOS2_DEFAULT_GVALUE);
   1372  1.1  mrg 
   1373  1.1  mrg   if (nios2_gpopt_option == gpopt_unspecified)
   1374  1.1  mrg     {
   1375  1.1  mrg       /* Default to -mgpopt unless -fpic or -fPIC.  */
   1376  1.1  mrg       if (flag_pic)
   1377  1.1  mrg 	nios2_gpopt_option = gpopt_none;
   1378  1.1  mrg       else
   1379  1.1  mrg 	nios2_gpopt_option = gpopt_local;
   1380  1.1  mrg     }
   1381  1.1  mrg 
   1382  1.1  mrg   /* GP-relative and r0-relative addressing don't make sense for PIC.  */
   1383  1.1  mrg   if (flag_pic)
   1384  1.1  mrg     {
   1385  1.1  mrg       if (nios2_gpopt_option != gpopt_none)
   1386  1.1  mrg 	error ("%<-mgpopt%> not supported with PIC");
   1387  1.1  mrg       if (nios2_gprel_sec)
   1388  1.1  mrg 	error ("%<-mgprel-sec=%> not supported with PIC");
   1389  1.1  mrg       if (nios2_r0rel_sec)
   1390  1.1  mrg 	error ("%<-mr0rel-sec=%> not supported with PIC");
   1391  1.1  mrg     }
   1392  1.1  mrg 
   1393  1.1  mrg   /* Process -mgprel-sec= and -m0rel-sec=.  */
   1394  1.1  mrg   if (nios2_gprel_sec)
   1395  1.1  mrg     {
   1396  1.1  mrg       if (regcomp (&nios2_gprel_sec_regex, nios2_gprel_sec,
   1397  1.1  mrg 		   REG_EXTENDED | REG_NOSUB))
   1398  1.1  mrg 	error ("%<-mgprel-sec=%> argument is not a valid regular expression");
   1399  1.1  mrg     }
   1400  1.1  mrg   if (nios2_r0rel_sec)
   1401  1.1  mrg     {
   1402  1.1  mrg       if (regcomp (&nios2_r0rel_sec_regex, nios2_r0rel_sec,
   1403  1.1  mrg 		   REG_EXTENDED | REG_NOSUB))
   1404  1.1  mrg 	error ("%<-mr0rel-sec=%> argument is not a valid regular expression");
   1405  1.1  mrg     }
   1406  1.1  mrg 
   1407  1.1  mrg   /* If we don't have mul, we don't have mulx either!  */
   1408  1.1  mrg   if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
   1409  1.1  mrg     target_flags &= ~MASK_HAS_MULX;
   1410  1.1  mrg 
   1411  1.1  mrg   /* Optional BMX and CDX instructions only make sense for R2.  */
   1412  1.1  mrg   if (!TARGET_ARCH_R2)
   1413  1.1  mrg     {
   1414  1.1  mrg       if (TARGET_HAS_BMX)
   1415  1.1  mrg 	error ("BMX instructions are only supported with R2 architecture");
   1416  1.1  mrg       if (TARGET_HAS_CDX)
   1417  1.1  mrg 	error ("CDX instructions are only supported with R2 architecture");
   1418  1.1  mrg     }
   1419  1.1  mrg 
   1420  1.1  mrg   /* R2 is little-endian only.  */
   1421  1.1  mrg   if (TARGET_ARCH_R2 && TARGET_BIG_ENDIAN)
   1422  1.1  mrg     error ("R2 architecture is little-endian only");
   1423  1.1  mrg 
   1424  1.1  mrg   /* Initialize default FPU configurations.  */
   1425  1.1  mrg   nios2_init_fpu_configs ();
   1426  1.1  mrg 
   1427  1.1  mrg   /* Set up default handling for floating point custom instructions.
   1428  1.1  mrg 
   1429  1.1  mrg      Putting things in this order means that the -mcustom-fpu-cfg=
   1430  1.1  mrg      switch will always be overridden by individual -mcustom-fadds=
   1431  1.1  mrg      switches, regardless of the order in which they were specified
   1432  1.1  mrg      on the command line.
   1433  1.1  mrg 
   1434  1.1  mrg      This behavior of prioritization of individual -mcustom-<insn>=
   1435  1.1  mrg      options before the -mcustom-fpu-cfg= switch is maintained for
   1436  1.1  mrg      compatibility.  */
   1437  1.1  mrg   if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
   1438  1.1  mrg     nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, NULL, false);
   1439  1.1  mrg 
   1440  1.1  mrg   /* Handle options for individual FPU insns.  */
   1441  1.1  mrg   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   1442  1.1  mrg     nios2_handle_custom_fpu_insn_option (i);
   1443  1.1  mrg 
   1444  1.1  mrg   nios2_custom_check_insns ();
   1445  1.1  mrg 
   1446  1.1  mrg   /* Save the initial options in case the user does function specific
   1447  1.1  mrg      options.  */
   1448  1.1  mrg   target_option_default_node = target_option_current_node
   1449  1.1  mrg     = build_target_option_node (&global_options, &global_options_set);
   1450  1.1  mrg }
   1451  1.1  mrg 
   1452  1.1  mrg 
   1453  1.1  mrg /* Return true if CST is a constant within range of movi/movui/movhi.  */
   1455  1.1  mrg static bool
   1456  1.1  mrg nios2_simple_const_p (const_rtx cst)
   1457  1.1  mrg {
   1458  1.1  mrg   if (!CONST_INT_P (cst))
   1459  1.1  mrg     return false;
   1460  1.1  mrg   HOST_WIDE_INT val = INTVAL (cst);
   1461  1.1  mrg   return SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val);
   1462  1.1  mrg }
   1463  1.1  mrg 
   1464  1.1  mrg /* Compute a (partial) cost for rtx X.  Return true if the complete
   1465  1.1  mrg    cost has been computed, and false if subexpressions should be
   1466  1.1  mrg    scanned.  In either case, *TOTAL contains the cost result.  */
   1467  1.1  mrg static bool
   1468  1.1  mrg nios2_rtx_costs (rtx x, machine_mode mode,
   1469  1.1  mrg 		 int outer_code,
   1470  1.1  mrg 		 int opno,
   1471  1.1  mrg 		 int *total, bool speed)
   1472  1.1  mrg {
   1473  1.1  mrg   int code = GET_CODE (x);
   1474  1.1  mrg 
   1475  1.1  mrg   switch (code)
   1476  1.1  mrg     {
   1477  1.1  mrg       case CONST_INT:
   1478  1.1  mrg         if (INTVAL (x) == 0 || nios2_simple_const_p (x))
   1479  1.1  mrg           {
   1480  1.1  mrg             *total = COSTS_N_INSNS (0);
   1481  1.1  mrg             return true;
   1482  1.1  mrg           }
   1483  1.1  mrg         else
   1484  1.1  mrg           {
   1485  1.1  mrg 	    /* High + lo_sum.  */
   1486  1.1  mrg             *total = COSTS_N_INSNS (1);
   1487  1.1  mrg             return true;
   1488  1.1  mrg           }
   1489  1.1  mrg 
   1490  1.1  mrg       case LABEL_REF:
   1491  1.1  mrg       case SYMBOL_REF:
   1492  1.1  mrg       case CONST:
   1493  1.1  mrg       case CONST_DOUBLE:
   1494  1.1  mrg 	if (gprel_constant_p (x) || r0rel_constant_p (x))
   1495  1.1  mrg           {
   1496  1.1  mrg             *total = COSTS_N_INSNS (1);
   1497  1.1  mrg             return true;
   1498  1.1  mrg           }
   1499  1.1  mrg 	else
   1500  1.1  mrg 	  {
   1501  1.1  mrg 	    /* High + lo_sum.  */
   1502  1.1  mrg 	    *total = COSTS_N_INSNS (1);
   1503  1.1  mrg 	    return true;
   1504  1.1  mrg 	  }
   1505  1.1  mrg 
   1506  1.1  mrg       case HIGH:
   1507  1.1  mrg 	{
   1508  1.1  mrg 	  /* This is essentially a constant.  */
   1509  1.1  mrg 	  *total = COSTS_N_INSNS (0);
   1510  1.1  mrg 	  return true;
   1511  1.1  mrg 	}
   1512  1.1  mrg 
   1513  1.1  mrg       case LO_SUM:
   1514  1.1  mrg 	{
   1515  1.1  mrg 	  *total = COSTS_N_INSNS (0);
   1516  1.1  mrg 	  return true;
   1517  1.1  mrg 	}
   1518  1.1  mrg 
   1519  1.1  mrg       case AND:
   1520  1.1  mrg 	{
   1521  1.1  mrg 	  /* Recognize 'nor' insn pattern.  */
   1522  1.1  mrg 	  if (GET_CODE (XEXP (x, 0)) == NOT
   1523  1.1  mrg 	      && GET_CODE (XEXP (x, 1)) == NOT)
   1524  1.1  mrg 	    {
   1525  1.1  mrg 	      *total = COSTS_N_INSNS (1);
   1526  1.1  mrg 	      return true;
   1527  1.1  mrg 	    }
   1528  1.1  mrg 	  return false;
   1529  1.1  mrg 	}
   1530  1.1  mrg 
   1531  1.1  mrg       /* For insns that have an execution latency (3 cycles), don't
   1532  1.1  mrg 	 penalize by the full amount since we can often schedule
   1533  1.1  mrg 	 to avoid it.  */
   1534  1.1  mrg       case MULT:
   1535  1.1  mrg         {
   1536  1.1  mrg 	  if (!TARGET_HAS_MUL)
   1537  1.1  mrg 	    *total = COSTS_N_INSNS (5);  /* Guess?  */
   1538  1.1  mrg 	  else if (speed)
   1539  1.1  mrg 	    *total = COSTS_N_INSNS (2);  /* Latency adjustment.  */
   1540  1.1  mrg 	  else
   1541  1.1  mrg 	    *total = COSTS_N_INSNS (1);
   1542  1.1  mrg 	  if (TARGET_HAS_MULX && GET_MODE (x) == DImode)
   1543  1.1  mrg 	    {
   1544  1.1  mrg 	      enum rtx_code c0 = GET_CODE (XEXP (x, 0));
   1545  1.1  mrg 	      enum rtx_code c1 = GET_CODE (XEXP (x, 1));
   1546  1.1  mrg 	      if ((c0 == SIGN_EXTEND && c1 == SIGN_EXTEND)
   1547  1.1  mrg 		  || (c0 == ZERO_EXTEND && c1 == ZERO_EXTEND))
   1548  1.1  mrg 		/* This is the <mul>sidi3 pattern, which expands into 4 insns,
   1549  1.1  mrg 		   2 multiplies and 2 moves.  */
   1550  1.1  mrg 		{
   1551  1.1  mrg 		  *total = *total * 2 + COSTS_N_INSNS (2);
   1552  1.1  mrg 		  return true;
   1553  1.1  mrg 		}
   1554  1.1  mrg 	    }
   1555  1.1  mrg           return false;
   1556  1.1  mrg         }
   1557  1.1  mrg 
   1558  1.1  mrg       case DIV:
   1559  1.1  mrg         {
   1560  1.1  mrg 	  if (!TARGET_HAS_DIV)
   1561  1.1  mrg 	    *total = COSTS_N_INSNS (5);  /* Guess?  */
   1562  1.1  mrg 	  else if (speed)
   1563  1.1  mrg 	    *total = COSTS_N_INSNS (2);  /* Latency adjustment.  */
   1564  1.1  mrg 	  else
   1565  1.1  mrg 	    *total = COSTS_N_INSNS (1);
   1566  1.1  mrg           return false;
   1567  1.1  mrg         }
   1568  1.1  mrg 
   1569  1.1  mrg       case ASHIFT:
   1570  1.1  mrg       case ASHIFTRT:
   1571  1.1  mrg       case LSHIFTRT:
   1572  1.1  mrg       case ROTATE:
   1573  1.1  mrg         {
   1574  1.1  mrg 	  if (!speed)
   1575  1.1  mrg 	    *total = COSTS_N_INSNS (1);
   1576  1.1  mrg 	  else
   1577  1.1  mrg 	    *total = COSTS_N_INSNS (2);  /* Latency adjustment.  */
   1578  1.1  mrg           return false;
   1579  1.1  mrg         }
   1580  1.1  mrg 
   1581  1.1  mrg       case ZERO_EXTRACT:
   1582  1.1  mrg 	if (TARGET_HAS_BMX)
   1583  1.1  mrg 	  {
   1584  1.1  mrg 	    *total = COSTS_N_INSNS (1);
   1585  1.1  mrg 	    return true;
   1586  1.1  mrg 	  }
   1587  1.1  mrg 	return false;
   1588  1.1  mrg 
   1589  1.1  mrg       case SIGN_EXTEND:
   1590  1.1  mrg         {
   1591  1.1  mrg 	  if (MEM_P (XEXP (x, 0)))
   1592  1.1  mrg 	    *total = COSTS_N_INSNS (1);
   1593  1.1  mrg 	  else
   1594  1.1  mrg 	    *total = COSTS_N_INSNS (3);
   1595  1.1  mrg 	  return false;
   1596  1.1  mrg 	}
   1597  1.1  mrg 
   1598  1.1  mrg       case MEM:
   1599  1.1  mrg 	{
   1600  1.1  mrg 	  rtx addr = XEXP (x, 0);
   1601  1.1  mrg 
   1602  1.1  mrg 	  /* Account for cost of different addressing modes.  */
   1603  1.1  mrg 	  *total = nios2_address_cost (addr, mode, ADDR_SPACE_GENERIC, speed);
   1604  1.1  mrg 
   1605  1.1  mrg 	  if (outer_code == SET && opno == 0)
   1606  1.1  mrg 	    /* Stores execute in 1 cycle accounted for by
   1607  1.1  mrg 	       the outer SET.  */
   1608  1.1  mrg 	    ;
   1609  1.1  mrg 	  else if (outer_code == SET || outer_code == SIGN_EXTEND
   1610  1.1  mrg 		   || outer_code == ZERO_EXTEND)
   1611  1.1  mrg 	    /* Latency adjustment.  */
   1612  1.1  mrg 	    {
   1613  1.1  mrg 	      if (speed)
   1614  1.1  mrg 		*total += COSTS_N_INSNS (1);
   1615  1.1  mrg 	    }
   1616  1.1  mrg 	  else
   1617  1.1  mrg 	    /* This is going to have to be split into a load.  */
   1618  1.1  mrg 	    *total += COSTS_N_INSNS (speed ? 2 : 1);
   1619  1.1  mrg 	  return true;
   1620  1.1  mrg 	}
   1621  1.1  mrg 
   1622  1.1  mrg       default:
   1623  1.1  mrg         return false;
   1624  1.1  mrg     }
   1625  1.1  mrg }
   1626  1.1  mrg 
   1627  1.1  mrg /* Implement TARGET_PREFERRED_RELOAD_CLASS.  */
   1628  1.1  mrg static reg_class_t
   1629  1.1  mrg nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass)
   1630  1.1  mrg {
   1631  1.1  mrg   return regclass == NO_REGS ? GENERAL_REGS : regclass;
   1632  1.1  mrg }
   1633  1.1  mrg 
   1634  1.1  mrg /* Emit a call to __tls_get_addr.  TI is the argument to this function.
   1635  1.1  mrg    RET is an RTX for the return value location.  The entire insn sequence
   1636  1.1  mrg    is returned.  */
   1637  1.1  mrg static GTY(()) rtx nios2_tls_symbol;
   1638  1.1  mrg 
   1639  1.1  mrg static rtx
   1640  1.1  mrg nios2_call_tls_get_addr (rtx ti)
   1641  1.1  mrg {
   1642  1.1  mrg   rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
   1643  1.1  mrg   rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO);
   1644  1.1  mrg   rtx fn;
   1645  1.1  mrg   rtx_insn *insn;
   1646  1.1  mrg 
   1647  1.1  mrg   if (!nios2_tls_symbol)
   1648  1.1  mrg     nios2_tls_symbol = init_one_libfunc ("__tls_get_addr");
   1649  1.1  mrg 
   1650  1.1  mrg   emit_move_insn (arg, ti);
   1651  1.1  mrg   fn = gen_rtx_MEM (QImode, nios2_tls_symbol);
   1652  1.1  mrg   insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
   1653  1.1  mrg   RTL_CONST_CALL_P (insn) = 1;
   1654  1.1  mrg   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
   1655  1.1  mrg   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
   1656  1.1  mrg 
   1657  1.1  mrg   return ret;
   1658  1.1  mrg }
   1659  1.1  mrg 
   1660  1.1  mrg /* Return true for large offsets requiring hiadj/lo relocation pairs.  */
   1661  1.1  mrg static bool
   1662  1.1  mrg nios2_large_offset_p (int unspec)
   1663  1.1  mrg {
   1664  1.1  mrg   gcc_assert (nios2_unspec_reloc_name (unspec) != NULL);
   1665  1.1  mrg 
   1666  1.1  mrg   if (flag_pic == 2
   1667  1.1  mrg       /* FIXME: TLS GOT offset relocations will eventually also get this
   1668  1.1  mrg 	 treatment, after binutils support for those are also completed.  */
   1669  1.1  mrg       && (unspec == UNSPEC_PIC_SYM || unspec == UNSPEC_PIC_CALL_SYM))
   1670  1.1  mrg     return true;
   1671  1.1  mrg 
   1672  1.1  mrg   /* 'gotoff' offsets are always hiadj/lo.  */
   1673  1.1  mrg   if (unspec == UNSPEC_PIC_GOTOFF_SYM)
   1674  1.1  mrg     return true;
   1675  1.1  mrg 
   1676  1.1  mrg   return false;
   1677  1.1  mrg }
   1678  1.1  mrg 
   1679  1.1  mrg /* Return true for conforming unspec relocations.  Also used in
   1680  1.1  mrg    constraints.md and predicates.md.  */
   1681  1.1  mrg bool
   1682  1.1  mrg nios2_unspec_reloc_p (rtx op)
   1683  1.1  mrg {
   1684  1.1  mrg   return (GET_CODE (op) == CONST
   1685  1.1  mrg 	  && GET_CODE (XEXP (op, 0)) == UNSPEC
   1686  1.1  mrg 	  && ! nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
   1687  1.1  mrg }
   1688  1.1  mrg 
   1689  1.1  mrg static bool
   1690  1.1  mrg nios2_large_unspec_reloc_p (rtx op)
   1691  1.1  mrg {
   1692  1.1  mrg   return (GET_CODE (op) == CONST
   1693  1.1  mrg 	  && GET_CODE (XEXP (op, 0)) == UNSPEC
   1694  1.1  mrg 	  && nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
   1695  1.1  mrg }
   1696  1.1  mrg 
   1697  1.1  mrg /* Helper to generate unspec constant.  */
   1698  1.1  mrg static rtx
   1699  1.1  mrg nios2_unspec_offset (rtx loc, int unspec)
   1700  1.1  mrg {
   1701  1.1  mrg   return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
   1702  1.1  mrg 					       unspec));
   1703  1.1  mrg }
   1704  1.1  mrg 
   1705  1.1  mrg /* Generate GOT pointer based address with large offset.  */
   1706  1.1  mrg static rtx
   1707  1.1  mrg nios2_large_got_address (rtx offset, rtx tmp)
   1708  1.1  mrg {
   1709  1.1  mrg   if (!tmp)
   1710  1.1  mrg     tmp = gen_reg_rtx (Pmode);
   1711  1.1  mrg   emit_move_insn (tmp, offset);
   1712  1.1  mrg   return gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
   1713  1.1  mrg }
   1714  1.1  mrg 
   1715  1.1  mrg /* Generate a GOT pointer based address.  */
   1716  1.1  mrg static rtx
   1717  1.1  mrg nios2_got_address (rtx loc, int unspec)
   1718  1.1  mrg {
   1719  1.1  mrg   rtx offset = nios2_unspec_offset (loc, unspec);
   1720  1.1  mrg   crtl->uses_pic_offset_table = 1;
   1721  1.1  mrg 
   1722  1.1  mrg   if (nios2_large_offset_p (unspec))
   1723  1.1  mrg     return force_reg (Pmode, nios2_large_got_address (offset, NULL_RTX));
   1724  1.1  mrg 
   1725  1.1  mrg   return gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
   1726  1.1  mrg }
   1727  1.1  mrg 
   1728  1.1  mrg /* Generate the code to access LOC, a thread local SYMBOL_REF.  The
   1729  1.1  mrg    return value will be a valid address and move_operand (either a REG
   1730  1.1  mrg    or a LO_SUM).  */
   1731  1.1  mrg static rtx
   1732  1.1  mrg nios2_legitimize_tls_address (rtx loc)
   1733  1.1  mrg {
   1734  1.1  mrg   rtx tmp, mem, tp;
   1735  1.1  mrg   enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
   1736  1.1  mrg 
   1737  1.1  mrg   switch (model)
   1738  1.1  mrg     {
   1739  1.1  mrg     case TLS_MODEL_GLOBAL_DYNAMIC:
   1740  1.1  mrg       tmp = gen_reg_rtx (Pmode);
   1741  1.1  mrg       emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_GD));
   1742  1.1  mrg       return nios2_call_tls_get_addr (tmp);
   1743  1.1  mrg 
   1744  1.1  mrg     case TLS_MODEL_LOCAL_DYNAMIC:
   1745  1.1  mrg       tmp = gen_reg_rtx (Pmode);
   1746  1.1  mrg       emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_LDM));
   1747  1.1  mrg       return gen_rtx_PLUS (Pmode, nios2_call_tls_get_addr (tmp),
   1748  1.1  mrg 			   nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LDO));
   1749  1.1  mrg 
   1750  1.1  mrg     case TLS_MODEL_INITIAL_EXEC:
   1751  1.1  mrg       tmp = gen_reg_rtx (Pmode);
   1752  1.1  mrg       mem = gen_const_mem (Pmode, nios2_got_address (loc, UNSPEC_LOAD_TLS_IE));
   1753  1.1  mrg       emit_move_insn (tmp, mem);
   1754  1.1  mrg       tp = gen_rtx_REG (Pmode, TP_REGNO);
   1755  1.1  mrg       return gen_rtx_PLUS (Pmode, tp, tmp);
   1756  1.1  mrg 
   1757  1.1  mrg     case TLS_MODEL_LOCAL_EXEC:
   1758  1.1  mrg       tp = gen_rtx_REG (Pmode, TP_REGNO);
   1759  1.1  mrg       return gen_rtx_PLUS (Pmode, tp,
   1760  1.1  mrg 			   nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LE));
   1761  1.1  mrg     default:
   1762  1.1  mrg       gcc_unreachable ();
   1763  1.1  mrg     }
   1764  1.1  mrg }
   1765  1.1  mrg 
   1766  1.1  mrg /* Divide Support
   1767  1.1  mrg 
   1768  1.1  mrg    If -O3 is used, we want to output a table lookup for
   1769  1.1  mrg    divides between small numbers (both num and den >= 0
   1770  1.1  mrg    and < 0x10).  The overhead of this method in the worst
   1771  1.1  mrg    case is 40 bytes in the text section (10 insns) and
   1772  1.1  mrg    256 bytes in the data section.  Additional divides do
   1773  1.1  mrg    not incur additional penalties in the data section.
   1774  1.1  mrg 
   1775  1.1  mrg    Code speed is improved for small divides by about 5x
   1776  1.1  mrg    when using this method in the worse case (~9 cycles
   1777  1.1  mrg    vs ~45).  And in the worst case divides not within the
   1778  1.1  mrg    table are penalized by about 10% (~5 cycles vs ~45).
   1779  1.1  mrg    However in the typical case the penalty is not as bad
   1780  1.1  mrg    because doing the long divide in only 45 cycles is
   1781  1.1  mrg    quite optimistic.
   1782  1.1  mrg 
   1783  1.1  mrg    ??? would be nice to have some benchmarks other
   1784  1.1  mrg    than Dhrystone to back this up.
   1785  1.1  mrg 
   1786  1.1  mrg    This bit of expansion is to create this instruction
   1787  1.1  mrg    sequence as rtl.
   1788  1.1  mrg         or      $8, $4, $5
   1789  1.1  mrg         slli    $9, $4, 4
   1790  1.1  mrg         cmpgeui $3, $8, 16
   1791  1.1  mrg         beq     $3, $0, .L3
   1792  1.1  mrg         or      $10, $9, $5
   1793  1.1  mrg         add     $12, $11, divide_table
   1794  1.1  mrg         ldbu    $2, 0($12)
   1795  1.1  mrg         br      .L1
   1796  1.1  mrg .L3:
   1797  1.1  mrg         call    slow_div
   1798  1.1  mrg .L1:
   1799  1.1  mrg #       continue here with result in $2
   1800  1.1  mrg 
   1801  1.1  mrg    ??? Ideally I would like the libcall block to contain all
   1802  1.1  mrg    of this code, but I don't know how to do that.  What it
   1803  1.1  mrg    means is that if the divide can be eliminated, it may not
   1804  1.1  mrg    completely disappear.
   1805  1.1  mrg 
   1806  1.1  mrg    ??? The __divsi3_table label should ideally be moved out
   1807  1.1  mrg    of this block and into a global.  If it is placed into the
   1808  1.1  mrg    sdata section we can save even more cycles by doing things
   1809  1.1  mrg    gp relative.  */
   1810  1.1  mrg void
   1811  1.1  mrg nios2_emit_expensive_div (rtx *operands, machine_mode mode)
   1812  1.1  mrg {
   1813  1.1  mrg   rtx or_result, shift_left_result;
   1814  1.1  mrg   rtx lookup_value;
   1815  1.1  mrg   rtx_code_label *lab1, *lab3;
   1816  1.1  mrg   rtx_insn *insns;
   1817  1.1  mrg   rtx libfunc;
   1818  1.1  mrg   rtx final_result;
   1819  1.1  mrg   rtx_insn *tmp;
   1820  1.1  mrg   rtx table;
   1821  1.1  mrg 
   1822  1.1  mrg   /* It may look a little generic, but only SImode is supported for now.  */
   1823  1.1  mrg   gcc_assert (mode == SImode);
   1824  1.1  mrg   libfunc = optab_libfunc (sdiv_optab, SImode);
   1825  1.1  mrg 
   1826  1.1  mrg   lab1 = gen_label_rtx ();
   1827  1.1  mrg   lab3 = gen_label_rtx ();
   1828  1.1  mrg 
   1829  1.1  mrg   or_result = expand_simple_binop (SImode, IOR,
   1830  1.1  mrg                                    operands[1], operands[2],
   1831  1.1  mrg                                    0, 0, OPTAB_LIB_WIDEN);
   1832  1.1  mrg 
   1833  1.1  mrg   emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
   1834  1.1  mrg                            GET_MODE (or_result), 0, lab3);
   1835  1.1  mrg   JUMP_LABEL (get_last_insn ()) = lab3;
   1836  1.1  mrg 
   1837  1.1  mrg   shift_left_result = expand_simple_binop (SImode, ASHIFT,
   1838  1.1  mrg                                            operands[1], GEN_INT (4),
   1839  1.1  mrg                                            0, 0, OPTAB_LIB_WIDEN);
   1840  1.1  mrg 
   1841  1.1  mrg   lookup_value = expand_simple_binop (SImode, IOR,
   1842  1.1  mrg                                       shift_left_result, operands[2],
   1843  1.1  mrg                                       0, 0, OPTAB_LIB_WIDEN);
   1844  1.1  mrg   table = gen_rtx_PLUS (SImode, lookup_value,
   1845  1.1  mrg 			gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"));
   1846  1.1  mrg   convert_move (operands[0], gen_rtx_MEM (QImode, table), 1);
   1847  1.1  mrg 
   1848  1.1  mrg   tmp = emit_jump_insn (gen_jump (lab1));
   1849  1.1  mrg   JUMP_LABEL (tmp) = lab1;
   1850  1.1  mrg   emit_barrier ();
   1851  1.1  mrg 
   1852  1.1  mrg   emit_label (lab3);
   1853  1.1  mrg   LABEL_NUSES (lab3) = 1;
   1854  1.1  mrg 
   1855  1.1  mrg   start_sequence ();
   1856  1.1  mrg   final_result = emit_library_call_value (libfunc, NULL_RTX,
   1857  1.1  mrg                                           LCT_CONST, SImode,
   1858  1.1  mrg                                           operands[1], SImode,
   1859  1.1  mrg                                           operands[2], SImode);
   1860  1.1  mrg 
   1861  1.1  mrg   insns = get_insns ();
   1862  1.1  mrg   end_sequence ();
   1863  1.1  mrg   emit_libcall_block (insns, operands[0], final_result,
   1864  1.1  mrg                       gen_rtx_DIV (SImode, operands[1], operands[2]));
   1865  1.1  mrg 
   1866  1.1  mrg   emit_label (lab1);
   1867  1.1  mrg   LABEL_NUSES (lab1) = 1;
   1868  1.1  mrg }
   1869  1.1  mrg 
   1870  1.1  mrg 
   1871  1.1  mrg /* Branches and compares.  */
   1873  1.1  mrg 
   1874  1.1  mrg /* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant
   1875  1.1  mrg    comparison, e.g. >= 1 into > 0.  */
   1876  1.1  mrg static void
   1877  1.1  mrg nios2_alternate_compare_const (enum rtx_code code, rtx op,
   1878  1.1  mrg 			       enum rtx_code *alt_code, rtx *alt_op,
   1879  1.1  mrg 			       machine_mode mode)
   1880  1.1  mrg {
   1881  1.1  mrg   gcc_assert (CONST_INT_P (op));
   1882  1.1  mrg 
   1883  1.1  mrg   HOST_WIDE_INT opval = INTVAL (op);
   1884  1.1  mrg   enum rtx_code scode = signed_condition (code);
   1885  1.1  mrg   bool dec_p = (scode == LT || scode == GE);
   1886  1.1  mrg 
   1887  1.1  mrg   if (code == EQ || code == NE)
   1888  1.1  mrg     {
   1889  1.1  mrg       *alt_code = code;
   1890  1.1  mrg       *alt_op = op;
   1891  1.1  mrg       return;
   1892  1.1  mrg     }
   1893  1.1  mrg 
   1894  1.1  mrg   *alt_op = (dec_p
   1895  1.1  mrg 	     ? gen_int_mode (opval - 1, mode)
   1896  1.1  mrg 	     : gen_int_mode (opval + 1, mode));
   1897  1.1  mrg 
   1898  1.1  mrg   /* The required conversion between [>,>=] and [<,<=] is captured
   1899  1.1  mrg      by a reverse + swap of condition codes.  */
   1900  1.1  mrg   *alt_code = reverse_condition (swap_condition (code));
   1901  1.1  mrg 
   1902  1.1  mrg   {
   1903  1.1  mrg     /* Test if the incremented/decremented value crosses the over/underflow
   1904  1.1  mrg        boundary.  Supposedly, such boundary cases should already be transformed
   1905  1.1  mrg        into always-true/false or EQ conditions, so use an assertion here.  */
   1906  1.1  mrg     unsigned HOST_WIDE_INT alt_opval = INTVAL (*alt_op);
   1907  1.1  mrg     if (code == scode)
   1908  1.1  mrg       alt_opval ^= (1 << (GET_MODE_BITSIZE (mode) - 1));
   1909  1.1  mrg     alt_opval &= GET_MODE_MASK (mode);
   1910  1.1  mrg     gcc_assert (dec_p ? alt_opval != GET_MODE_MASK (mode) : alt_opval != 0);
   1911  1.1  mrg   }
   1912  1.1  mrg }
   1913  1.1  mrg 
   1914  1.1  mrg /* Return true if the constant comparison is supported by nios2.  */
   1915  1.1  mrg static bool
   1916  1.1  mrg nios2_valid_compare_const_p (enum rtx_code code, rtx op)
   1917  1.1  mrg {
   1918  1.1  mrg   gcc_assert (CONST_INT_P (op));
   1919  1.1  mrg   switch (code)
   1920  1.1  mrg     {
   1921  1.1  mrg     case EQ: case NE: case GE: case LT:
   1922  1.1  mrg       return SMALL_INT (INTVAL (op));
   1923  1.1  mrg     case GEU: case LTU:
   1924  1.1  mrg       return SMALL_INT_UNSIGNED (INTVAL (op));
   1925  1.1  mrg     default:
   1926  1.1  mrg       return false;
   1927  1.1  mrg     }
   1928  1.1  mrg }
   1929  1.1  mrg 
   1930  1.1  mrg /* Checks if the FPU comparison in *CMP, *OP1, and *OP2 can be supported in
   1931  1.1  mrg    the current configuration.  Perform modifications if MODIFY_P is true.
   1932  1.1  mrg    Returns true if FPU compare can be done.  */
   1933  1.1  mrg 
   1934  1.1  mrg bool
   1935  1.1  mrg nios2_validate_fpu_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2,
   1936  1.1  mrg 			    bool modify_p)
   1937  1.1  mrg {
   1938  1.1  mrg   bool rev_p = false;
   1939  1.1  mrg   enum rtx_code code = GET_CODE (*cmp);
   1940  1.1  mrg 
   1941  1.1  mrg   if (!nios2_fpu_compare_enabled (code, mode))
   1942  1.1  mrg     {
   1943  1.1  mrg       code = swap_condition (code);
   1944  1.1  mrg       if (nios2_fpu_compare_enabled (code, mode))
   1945  1.1  mrg 	rev_p = true;
   1946  1.1  mrg       else
   1947  1.1  mrg 	return false;
   1948  1.1  mrg     }
   1949  1.1  mrg 
   1950  1.1  mrg   if (modify_p)
   1951  1.1  mrg     {
   1952  1.1  mrg       if (rev_p)
   1953  1.1  mrg 	{
   1954  1.1  mrg 	  rtx tmp = *op1;
   1955  1.1  mrg 	  *op1 = *op2;
   1956  1.1  mrg 	  *op2 = tmp;
   1957  1.1  mrg 	}
   1958  1.1  mrg       *op1 = force_reg (mode, *op1);
   1959  1.1  mrg       *op2 = force_reg (mode, *op2);
   1960  1.1  mrg       *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
   1961  1.1  mrg     }
   1962  1.1  mrg   return true;
   1963  1.1  mrg }
   1964  1.1  mrg 
   1965  1.1  mrg /* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid
   1966  1.1  mrg    nios2 supported form.  Returns true if success.  */
   1967  1.1  mrg bool
   1968  1.1  mrg nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
   1969  1.1  mrg {
   1970  1.1  mrg   enum rtx_code code = GET_CODE (*cmp);
   1971  1.1  mrg   enum rtx_code alt_code;
   1972  1.1  mrg   rtx alt_op2;
   1973  1.1  mrg 
   1974  1.1  mrg   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
   1975  1.1  mrg     return nios2_validate_fpu_compare (mode, cmp, op1, op2, true);
   1976  1.1  mrg 
   1977  1.1  mrg   if (CONST_INT_P (*op2) && *op2 != const0_rtx)
   1978  1.1  mrg     {
   1979  1.1  mrg       /* Create alternate constant compare.  */
   1980  1.1  mrg       nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode);
   1981  1.1  mrg 
   1982  1.1  mrg       /* If alterate op2 is zero(0), we can use it directly, possibly
   1983  1.1  mrg 	 swapping the compare code.  */
   1984  1.1  mrg       if (alt_op2 == const0_rtx)
   1985  1.1  mrg 	{
   1986  1.1  mrg 	  code = alt_code;
   1987  1.1  mrg 	  *op2 = alt_op2;
   1988  1.1  mrg 	  goto check_rebuild_cmp;
   1989  1.1  mrg 	}
   1990  1.1  mrg 
   1991  1.1  mrg       /* Check if either constant compare can be used.  */
   1992  1.1  mrg       if (nios2_valid_compare_const_p (code, *op2))
   1993  1.1  mrg 	return true;
   1994  1.1  mrg       else if (nios2_valid_compare_const_p (alt_code, alt_op2))
   1995  1.1  mrg 	{
   1996  1.1  mrg 	  code = alt_code;
   1997  1.1  mrg 	  *op2 = alt_op2;
   1998  1.1  mrg 	  goto rebuild_cmp;
   1999  1.1  mrg 	}
   2000  1.1  mrg 
   2001  1.1  mrg       /* We have to force op2 into a register now.  Try to pick one
   2002  1.1  mrg 	 with a lower cost.  */
   2003  1.1  mrg       if (! nios2_simple_const_p (*op2)
   2004  1.1  mrg 	  && nios2_simple_const_p (alt_op2))
   2005  1.1  mrg 	{
   2006  1.1  mrg 	  code = alt_code;
   2007  1.1  mrg 	  *op2 = alt_op2;
   2008  1.1  mrg 	}
   2009  1.1  mrg       *op2 = force_reg (mode, *op2);
   2010  1.1  mrg     }
   2011  1.1  mrg     else if (!reg_or_0_operand (*op2, mode))
   2012  1.1  mrg       *op2 = force_reg (mode, *op2);
   2013  1.1  mrg 
   2014  1.1  mrg  check_rebuild_cmp:
   2015  1.1  mrg   if (code == GT || code == GTU || code == LE || code == LEU)
   2016  1.1  mrg     {
   2017  1.1  mrg       rtx t = *op1; *op1 = *op2; *op2 = t;
   2018  1.1  mrg       code = swap_condition (code);
   2019  1.1  mrg     }
   2020  1.1  mrg  rebuild_cmp:
   2021  1.1  mrg   *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
   2022  1.1  mrg   return true;
   2023  1.1  mrg }
   2024  1.1  mrg 
   2025  1.1  mrg 
   2026  1.1  mrg /* Addressing modes and constants.  */
   2027  1.1  mrg 
   2028  1.1  mrg /* Symbol references and other 32-bit constants are split into
   2029  1.1  mrg    high/lo_sum pairs during the split1 pass.  After that, they are not
   2030  1.1  mrg    considered legitimate addresses.
   2031  1.1  mrg    This function returns true if in a pre-split context where these
   2032  1.1  mrg    constants are allowed.  */
   2033  1.1  mrg static bool
   2034  1.1  mrg nios2_large_constant_allowed (void)
   2035  1.1  mrg {
   2036  1.1  mrg   /* The reload_completed check is for the benefit of
   2037  1.1  mrg      nios2_asm_output_mi_thunk and perhaps other places that try to
   2038  1.1  mrg      emulate a post-reload pass.  */
   2039  1.1  mrg   return !(cfun->curr_properties & PROP_rtl_split_insns) && !reload_completed;
   2040  1.1  mrg }
   2041  1.1  mrg 
   2042  1.1  mrg /* Return true if X is constant expression with a reference to an
   2043  1.1  mrg    "ordinary" symbol; not GOT-relative, not GP-relative, not TLS.  */
   2044  1.1  mrg static bool
   2045  1.1  mrg nios2_symbolic_constant_p (rtx x)
   2046  1.1  mrg {
   2047  1.1  mrg   rtx base, offset;
   2048  1.1  mrg 
   2049  1.1  mrg   if (flag_pic)
   2050  1.1  mrg     return false;
   2051  1.1  mrg   if (GET_CODE (x) == LABEL_REF)
   2052  1.1  mrg     return true;
   2053  1.1  mrg   else if (CONSTANT_P (x))
   2054  1.1  mrg     {
   2055  1.1  mrg       split_const (x, &base, &offset);
   2056  1.1  mrg       return (SYMBOL_REF_P (base)
   2057  1.1  mrg 		&& !SYMBOL_REF_TLS_MODEL (base)
   2058  1.1  mrg 		&& !gprel_constant_p (base)
   2059  1.1  mrg 		&& !r0rel_constant_p (base)
   2060  1.1  mrg 		&& SMALL_INT (INTVAL (offset)));
   2061  1.1  mrg     }
   2062  1.1  mrg   return false;
   2063  1.1  mrg }
   2064  1.1  mrg 
   2065  1.1  mrg /* Return true if X is an expression of the form
   2066  1.1  mrg    (PLUS reg large_constant).  */
   2067  1.1  mrg static bool
   2068  1.1  mrg nios2_plus_large_constant_p (rtx x)
   2069  1.1  mrg {
   2070  1.1  mrg   return (GET_CODE (x) == PLUS
   2071  1.1  mrg 	  && REG_P (XEXP (x, 0))
   2072  1.1  mrg 	  && nios2_large_constant_p (XEXP (x, 1)));
   2073  1.1  mrg }
   2074  1.1  mrg 
   2075  1.1  mrg /* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
   2076  1.1  mrg static bool
   2077  1.1  mrg nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
   2078  1.1  mrg {
   2079  1.1  mrg   rtx base, offset;
   2080  1.1  mrg   split_const (x, &base, &offset);
   2081  1.1  mrg   return GET_CODE (base) != SYMBOL_REF || !SYMBOL_REF_TLS_MODEL (base);
   2082  1.1  mrg }
   2083  1.1  mrg 
   2084  1.1  mrg /* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
   2085  1.1  mrg static bool
   2086  1.1  mrg nios2_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
   2087  1.1  mrg {
   2088  1.1  mrg   return nios2_legitimate_constant_p (mode, x) == false;
   2089  1.1  mrg }
   2090  1.1  mrg 
   2091  1.1  mrg /* Return true if register REGNO is a valid base register.
   2092  1.1  mrg    STRICT_P is true if REG_OK_STRICT is in effect.  */
   2093  1.1  mrg 
   2094  1.1  mrg bool
   2095  1.1  mrg nios2_regno_ok_for_base_p (int regno, bool strict_p)
   2096  1.1  mrg {
   2097  1.1  mrg   if (!HARD_REGISTER_NUM_P (regno))
   2098  1.1  mrg     {
   2099  1.1  mrg       if (!strict_p)
   2100  1.1  mrg 	return true;
   2101  1.1  mrg 
   2102  1.1  mrg       if (!reg_renumber)
   2103  1.1  mrg 	return false;
   2104  1.1  mrg 
   2105  1.1  mrg       regno = reg_renumber[regno];
   2106  1.1  mrg     }
   2107  1.1  mrg 
   2108  1.1  mrg   /* The fake registers will be eliminated to either the stack or
   2109  1.1  mrg      hard frame pointer, both of which are usually valid base registers.
   2110  1.1  mrg      Reload deals with the cases where the eliminated form isn't valid.  */
   2111  1.1  mrg   return (GP_REG_P (regno)
   2112  1.1  mrg 	  || regno == FRAME_POINTER_REGNUM
   2113  1.1  mrg 	  || regno == ARG_POINTER_REGNUM);
   2114  1.1  mrg }
   2115  1.1  mrg 
   2116  1.1  mrg /* Return true if OFFSET is permitted in a load/store address expression.
   2117  1.1  mrg    Normally any 16-bit value is permitted, but on R2 if we may be emitting
   2118  1.1  mrg    the IO forms of these instructions we must restrict the offset to fit
   2119  1.1  mrg    in a 12-bit field instead.  */
   2120  1.1  mrg 
   2121  1.1  mrg static bool
   2122  1.1  mrg nios2_valid_addr_offset_p (rtx offset)
   2123  1.1  mrg {
   2124  1.1  mrg   return (CONST_INT_P (offset)
   2125  1.1  mrg 	  && ((TARGET_ARCH_R2 && (TARGET_BYPASS_CACHE
   2126  1.1  mrg 				  || TARGET_BYPASS_CACHE_VOLATILE))
   2127  1.1  mrg 	      ? SMALL_INT12 (INTVAL (offset))
   2128  1.1  mrg 	      : SMALL_INT (INTVAL (offset))));
   2129  1.1  mrg }
   2130  1.1  mrg 
   2131  1.1  mrg /* Return true if the address expression formed by BASE + OFFSET is
   2132  1.1  mrg    valid.  */
   2133  1.1  mrg static bool
   2134  1.1  mrg nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
   2135  1.1  mrg {
   2136  1.1  mrg   if (!strict_p && GET_CODE (base) == SUBREG)
   2137  1.1  mrg     base = SUBREG_REG (base);
   2138  1.1  mrg   return (REG_P (base)
   2139  1.1  mrg 	  && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
   2140  1.1  mrg 	  && (offset == NULL_RTX
   2141  1.1  mrg 	      || nios2_valid_addr_offset_p (offset)
   2142  1.1  mrg 	      || (nios2_large_constant_allowed ()
   2143  1.1  mrg 		  && nios2_symbolic_constant_p (offset))
   2144  1.1  mrg 	      || nios2_unspec_reloc_p (offset)));
   2145  1.1  mrg }
   2146  1.1  mrg 
   2147  1.1  mrg /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
   2148  1.1  mrg static bool
   2149  1.1  mrg nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
   2150  1.1  mrg 			    rtx operand, bool strict_p)
   2151  1.1  mrg {
   2152  1.1  mrg   switch (GET_CODE (operand))
   2153  1.1  mrg     {
   2154  1.1  mrg       /* Direct.  */
   2155  1.1  mrg     case SYMBOL_REF:
   2156  1.1  mrg       if (SYMBOL_REF_TLS_MODEL (operand))
   2157  1.1  mrg 	return false;
   2158  1.1  mrg 
   2159  1.1  mrg       /* Else, fall through.  */
   2160  1.1  mrg     case CONST:
   2161  1.1  mrg       if (gprel_constant_p (operand) || r0rel_constant_p (operand))
   2162  1.1  mrg 	return true;
   2163  1.1  mrg 
   2164  1.1  mrg       /* Else, fall through.  */
   2165  1.1  mrg     case LABEL_REF:
   2166  1.1  mrg       if (nios2_large_constant_allowed ()
   2167  1.1  mrg 	  && nios2_symbolic_constant_p (operand))
   2168  1.1  mrg 	return true;
   2169  1.1  mrg       return false;
   2170  1.1  mrg 
   2171  1.1  mrg     case CONST_INT:
   2172  1.1  mrg       if (r0rel_constant_p (operand))
   2173  1.1  mrg 	return true;
   2174  1.1  mrg       return nios2_large_constant_allowed ();
   2175  1.1  mrg 
   2176  1.1  mrg     case CONST_DOUBLE:
   2177  1.1  mrg       return false;
   2178  1.1  mrg 
   2179  1.1  mrg       /* Register indirect.  */
   2180  1.1  mrg     case REG:
   2181  1.1  mrg       return nios2_regno_ok_for_base_p (REGNO (operand), strict_p);
   2182  1.1  mrg 
   2183  1.1  mrg       /* Register indirect with displacement.  */
   2184  1.1  mrg     case PLUS:
   2185  1.1  mrg       {
   2186  1.1  mrg         rtx op0 = XEXP (operand, 0);
   2187  1.1  mrg         rtx op1 = XEXP (operand, 1);
   2188  1.1  mrg 
   2189  1.1  mrg 	if (nios2_valid_addr_expr_p (op0, op1, strict_p)
   2190  1.1  mrg 	    || nios2_valid_addr_expr_p (op1, op0, strict_p))
   2191  1.1  mrg 	  return true;
   2192  1.1  mrg       }
   2193  1.1  mrg       break;
   2194  1.1  mrg 
   2195  1.1  mrg       /* %lo(constant)(reg)
   2196  1.1  mrg 	 This requires a 16-bit relocation and isn't valid with R2
   2197  1.1  mrg 	 io-variant load/stores.  */
   2198  1.1  mrg     case LO_SUM:
   2199  1.1  mrg       if (TARGET_ARCH_R2
   2200  1.1  mrg 	  && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
   2201  1.1  mrg 	return false;
   2202  1.1  mrg       else
   2203  1.1  mrg 	{
   2204  1.1  mrg 	  rtx op0 = XEXP (operand, 0);
   2205  1.1  mrg 	  rtx op1 = XEXP (operand, 1);
   2206  1.1  mrg 
   2207  1.1  mrg 	  return (REG_P (op0)
   2208  1.1  mrg 		  && nios2_regno_ok_for_base_p (REGNO (op0), strict_p)
   2209  1.1  mrg 		  && nios2_large_constant_p (op1));
   2210  1.1  mrg 	}
   2211  1.1  mrg 
   2212  1.1  mrg     default:
   2213  1.1  mrg       break;
   2214  1.1  mrg     }
   2215  1.1  mrg   return false;
   2216  1.1  mrg }
   2217  1.1  mrg 
   2218  1.1  mrg /* Implement TARGET_ADDRESS_COST.
   2219  1.1  mrg    Experimentation has shown that we get better code by penalizing the
   2220  1.1  mrg    the (plus reg symbolic_constant) and (plus reg (const ...)) forms
   2221  1.1  mrg    but giving (plus reg symbol_ref) address modes the same cost as those
   2222  1.1  mrg    that don't require splitting.  Also, from a theoretical point of view:
   2223  1.1  mrg    - This is in line with the recommendation in the GCC internals
   2224  1.1  mrg      documentation to make address forms involving multiple
   2225  1.1  mrg      registers more expensive than single-register forms.
   2226  1.1  mrg    - OTOH it still encourages fwprop1 to propagate constants into
   2227  1.1  mrg      address expressions more aggressively.
   2228  1.1  mrg    - We should discourage splitting (symbol + offset) into hi/lo pairs
   2229  1.1  mrg      to allow CSE'ing the symbol when it's used with more than one offset,
   2230  1.1  mrg      but not so heavily as to avoid this addressing mode at all.  */
   2231  1.1  mrg static int
   2232  1.1  mrg nios2_address_cost (rtx address,
   2233  1.1  mrg 		    machine_mode mode ATTRIBUTE_UNUSED,
   2234  1.1  mrg 		    addr_space_t as ATTRIBUTE_UNUSED,
   2235  1.1  mrg 		    bool speed ATTRIBUTE_UNUSED)
   2236  1.1  mrg {
   2237  1.1  mrg   if (nios2_plus_large_constant_p (address))
   2238  1.1  mrg     return COSTS_N_INSNS (1);
   2239  1.1  mrg   if (nios2_large_constant_p (address))
   2240  1.1  mrg     {
   2241  1.1  mrg       if (GET_CODE (address) == CONST)
   2242  1.1  mrg 	return COSTS_N_INSNS (1);
   2243  1.1  mrg       else
   2244  1.1  mrg 	return COSTS_N_INSNS (0);
   2245  1.1  mrg     }
   2246  1.1  mrg   return COSTS_N_INSNS (0);
   2247  1.1  mrg }
   2248  1.1  mrg 
   2249  1.1  mrg /* Return true if X is a MEM whose address expression involves a large (32-bit)
   2250  1.1  mrg    constant.  */
   2251  1.1  mrg bool
   2252  1.1  mrg nios2_large_constant_memory_operand_p (rtx x)
   2253  1.1  mrg {
   2254  1.1  mrg   rtx addr;
   2255  1.1  mrg 
   2256  1.1  mrg   if (GET_CODE (x) != MEM)
   2257  1.1  mrg     return false;
   2258  1.1  mrg   addr = XEXP (x, 0);
   2259  1.1  mrg 
   2260  1.1  mrg   return (nios2_large_constant_p (addr)
   2261  1.1  mrg 	  || nios2_plus_large_constant_p (addr));
   2262  1.1  mrg }
   2263  1.1  mrg 
   2264  1.1  mrg 
   2265  1.1  mrg /* Return true if X is something that needs to be split into a
   2266  1.1  mrg    high/lo_sum pair.  */
   2267  1.1  mrg bool
   2268  1.1  mrg nios2_large_constant_p (rtx x)
   2269  1.1  mrg {
   2270  1.1  mrg   return (nios2_symbolic_constant_p (x)
   2271  1.1  mrg 	  || nios2_large_unspec_reloc_p (x)
   2272  1.1  mrg 	  || (CONST_INT_P (x) && !SMALL_INT (INTVAL (x))));
   2273  1.1  mrg }
   2274  1.1  mrg 
   2275  1.1  mrg /* Given an RTX X that satisfies nios2_large_constant_p, split it into
   2276  1.1  mrg    high and lo_sum parts using TEMP as a scratch register.  Emit the high
   2277  1.1  mrg    instruction and return the lo_sum expression.
   2278  1.1  mrg    Also handle special cases involving constant integers.  */
   2279  1.1  mrg rtx
   2280  1.1  mrg nios2_split_large_constant (rtx x, rtx temp)
   2281  1.1  mrg {
   2282  1.1  mrg   if (CONST_INT_P (x))
   2283  1.1  mrg     {
   2284  1.1  mrg       HOST_WIDE_INT val = INTVAL (x);
   2285  1.1  mrg       if (SMALL_INT (val))
   2286  1.1  mrg 	return x;
   2287  1.1  mrg       else if (SMALL_INT_UNSIGNED (val) || UPPER16_INT (val))
   2288  1.1  mrg 	{
   2289  1.1  mrg 	  emit_move_insn (temp, x);
   2290  1.1  mrg 	  return temp;
   2291  1.1  mrg 	}
   2292  1.1  mrg       else
   2293  1.1  mrg 	{
   2294  1.1  mrg 	  HOST_WIDE_INT high = (val + 0x8000) & ~0xffff;
   2295  1.1  mrg 	  HOST_WIDE_INT low = val - high;
   2296  1.1  mrg 	  emit_move_insn (temp, gen_int_mode (high, Pmode));
   2297  1.1  mrg 	  return gen_rtx_PLUS (Pmode, temp, gen_int_mode (low, Pmode));
   2298  1.1  mrg 	}
   2299  1.1  mrg     }
   2300  1.1  mrg 
   2301  1.1  mrg   emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (x))));
   2302  1.1  mrg   return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (x));
   2303  1.1  mrg }
   2304  1.1  mrg 
   2305  1.1  mrg /* Split an RTX of the form
   2306  1.1  mrg      (plus op0 op1)
   2307  1.1  mrg    where op1 is a large constant into
   2308  1.1  mrg      (set temp (high op1))
   2309  1.1  mrg      (set temp (plus op0 temp))
   2310  1.1  mrg      (lo_sum temp op1)
   2311  1.1  mrg    returning the lo_sum expression as the value.  */
   2312  1.1  mrg static rtx
   2313  1.1  mrg nios2_split_plus_large_constant (rtx op0, rtx op1)
   2314  1.1  mrg {
   2315  1.1  mrg   rtx temp = gen_reg_rtx (Pmode);
   2316  1.1  mrg   op0 = force_reg (Pmode, op0);
   2317  1.1  mrg 
   2318  1.1  mrg   emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (op1))));
   2319  1.1  mrg   emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, op0, temp)));
   2320  1.1  mrg   return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (op1));
   2321  1.1  mrg }
   2322  1.1  mrg 
   2323  1.1  mrg /* Given a MEM OP with an address that includes a splittable symbol or
   2324  1.1  mrg    other large constant, emit some instructions to do the split and
   2325  1.1  mrg    return a new MEM.  */
   2326  1.1  mrg rtx
   2327  1.1  mrg nios2_split_large_constant_memory_operand (rtx op)
   2328  1.1  mrg {
   2329  1.1  mrg   rtx addr = XEXP (op, 0);
   2330  1.1  mrg 
   2331  1.1  mrg   if (nios2_large_constant_p (addr))
   2332  1.1  mrg     addr = nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
   2333  1.1  mrg   else if (nios2_plus_large_constant_p (addr))
   2334  1.1  mrg     addr = nios2_split_plus_large_constant (XEXP (addr, 0), XEXP (addr, 1));
   2335  1.1  mrg   else
   2336  1.1  mrg     gcc_unreachable ();
   2337  1.1  mrg   return replace_equiv_address (op, addr, false);
   2338  1.1  mrg }
   2339  1.1  mrg 
   2340  1.1  mrg /* Return true if SECTION is a small section name.  */
   2341  1.1  mrg static bool
   2342  1.1  mrg nios2_small_section_name_p (const char *section)
   2343  1.1  mrg {
   2344  1.1  mrg   return (strcmp (section, ".sbss") == 0
   2345  1.1  mrg 	  || startswith (section, ".sbss.")
   2346  1.1  mrg 	  || strcmp (section, ".sdata") == 0
   2347  1.1  mrg 	  || startswith (section, ".sdata.")
   2348  1.1  mrg 	  || (nios2_gprel_sec
   2349  1.1  mrg 	      && regexec (&nios2_gprel_sec_regex, section, 0, NULL, 0) == 0));
   2350  1.1  mrg }
   2351  1.1  mrg 
   2352  1.1  mrg /* Return true if SECTION is a r0-relative section name.  */
   2353  1.1  mrg static bool
   2354  1.1  mrg nios2_r0rel_section_name_p (const char *section)
   2355  1.1  mrg {
   2356  1.1  mrg   return (nios2_r0rel_sec
   2357  1.1  mrg 	  && regexec (&nios2_r0rel_sec_regex, section, 0, NULL, 0) == 0);
   2358  1.1  mrg }
   2359  1.1  mrg 
   2360  1.1  mrg /* Return true if EXP should be placed in the small data section.  */
   2361  1.1  mrg static bool
   2362  1.1  mrg nios2_in_small_data_p (const_tree exp)
   2363  1.1  mrg {
   2364  1.1  mrg   /* We want to merge strings, so we never consider them small data.  */
   2365  1.1  mrg   if (TREE_CODE (exp) == STRING_CST)
   2366  1.1  mrg     return false;
   2367  1.1  mrg 
   2368  1.1  mrg   if (TREE_CODE (exp) == VAR_DECL)
   2369  1.1  mrg     {
   2370  1.1  mrg       if (DECL_SECTION_NAME (exp))
   2371  1.1  mrg 	{
   2372  1.1  mrg 	  const char *section = DECL_SECTION_NAME (exp);
   2373  1.1  mrg 	  if (nios2_small_section_name_p (section))
   2374  1.1  mrg 	    return true;
   2375  1.1  mrg 	}
   2376  1.1  mrg       else if (flexible_array_type_p (TREE_TYPE (exp))
   2377  1.1  mrg 	       && (!TREE_PUBLIC (exp) || DECL_EXTERNAL (exp)))
   2378  1.1  mrg 	{
   2379  1.1  mrg 	  /* We really should not consider any objects of any flexibly-sized
   2380  1.1  mrg 	     type to be small data, but pre-GCC 10 did not test
   2381  1.1  mrg 	     for this and just fell through to the next case.  Thus older
   2382  1.1  mrg 	     code compiled with -mgpopt=global could contain GP-relative
   2383  1.1  mrg 	     accesses to objects defined in this compilation unit with
   2384  1.1  mrg 	     external linkage.  We retain the possible small-data treatment
   2385  1.1  mrg 	     of such definitions for backward ABI compatibility, but
   2386  1.1  mrg 	     no longer generate GP-relative accesses for external
   2387  1.1  mrg 	     references (so that the ABI could be changed in the future
   2388  1.1  mrg 	     with less potential impact), or objects with internal
   2389  1.1  mrg 	     linkage.  */
   2390  1.1  mrg 	  return false;
   2391  1.1  mrg 	}
   2392  1.1  mrg       else
   2393  1.1  mrg 	{
   2394  1.1  mrg 	  HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
   2395  1.1  mrg 
   2396  1.1  mrg 	  /* If this is an incomplete type with size 0, then we can't put it
   2397  1.1  mrg 	     in sdata because it might be too big when completed.  */
   2398  1.1  mrg 	  if (size > 0
   2399  1.1  mrg 	      && (unsigned HOST_WIDE_INT) size <= nios2_section_threshold)
   2400  1.1  mrg 	    return true;
   2401  1.1  mrg 	}
   2402  1.1  mrg     }
   2403  1.1  mrg 
   2404  1.1  mrg   return false;
   2405  1.1  mrg }
   2406  1.1  mrg 
   2407  1.1  mrg /* Return true if symbol is in small data section.  */
   2408  1.1  mrg 
   2409  1.1  mrg static bool
   2410  1.1  mrg nios2_symbol_ref_in_small_data_p (rtx sym)
   2411  1.1  mrg {
   2412  1.1  mrg   tree decl;
   2413  1.1  mrg 
   2414  1.1  mrg   gcc_assert (GET_CODE (sym) == SYMBOL_REF);
   2415  1.1  mrg   decl = SYMBOL_REF_DECL (sym);
   2416  1.1  mrg 
   2417  1.1  mrg   /* TLS variables are not accessed through the GP.  */
   2418  1.1  mrg   if (SYMBOL_REF_TLS_MODEL (sym) != 0)
   2419  1.1  mrg     return false;
   2420  1.1  mrg 
   2421  1.1  mrg   /* On Nios II R2, there is no GP-relative relocation that can be
   2422  1.1  mrg      used with "io" instructions.  So, if we are implicitly generating
   2423  1.1  mrg      those instructions, we cannot emit GP-relative accesses.  */
   2424  1.1  mrg   if (TARGET_ARCH_R2
   2425  1.1  mrg       && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
   2426  1.1  mrg     return false;
   2427  1.1  mrg 
   2428  1.1  mrg   /* If the user has explicitly placed the symbol in a small data section
   2429  1.1  mrg      via an attribute, generate gp-relative addressing even if the symbol
   2430  1.1  mrg      is external, weak, or larger than we'd automatically put in the
   2431  1.1  mrg      small data section.  OTOH, if the symbol is located in some
   2432  1.1  mrg      non-small-data section, we can't use gp-relative accesses on it
   2433  1.1  mrg      unless the user has requested gpopt_data or gpopt_all.  */
   2434  1.1  mrg 
   2435  1.1  mrg   switch (nios2_gpopt_option)
   2436  1.1  mrg     {
   2437  1.1  mrg     case gpopt_none:
   2438  1.1  mrg       /* Don't generate a gp-relative addressing mode if that's been
   2439  1.1  mrg 	 disabled.  */
   2440  1.1  mrg       return false;
   2441  1.1  mrg 
   2442  1.1  mrg     case gpopt_local:
   2443  1.1  mrg       /* Use GP-relative addressing for small data symbols that are
   2444  1.1  mrg 	 not external or weak or uninitialized common, plus any symbols
   2445  1.1  mrg 	 that have explicitly been placed in a small data section.  */
   2446  1.1  mrg       if (decl && DECL_SECTION_NAME (decl))
   2447  1.1  mrg 	return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
   2448  1.1  mrg       return (SYMBOL_REF_SMALL_P (sym)
   2449  1.1  mrg 	      && !SYMBOL_REF_EXTERNAL_P (sym)
   2450  1.1  mrg 	      && !(decl && DECL_WEAK (decl))
   2451  1.1  mrg 	      && !(decl && DECL_COMMON (decl)
   2452  1.1  mrg 		   && (DECL_INITIAL (decl) == NULL
   2453  1.1  mrg 		       || (!in_lto_p
   2454  1.1  mrg 			   && DECL_INITIAL (decl) == error_mark_node))));
   2455  1.1  mrg 
   2456  1.1  mrg     case gpopt_global:
   2457  1.1  mrg       /* Use GP-relative addressing for small data symbols, even if
   2458  1.1  mrg 	 they are external or weak.  Note that SYMBOL_REF_SMALL_P
   2459  1.1  mrg          is also true of symbols that have explicitly been placed
   2460  1.1  mrg          in a small data section.  */
   2461  1.1  mrg       return SYMBOL_REF_SMALL_P (sym);
   2462  1.1  mrg 
   2463  1.1  mrg     case gpopt_data:
   2464  1.1  mrg       /* Use GP-relative addressing for all data symbols regardless
   2465  1.1  mrg 	 of the object size, but not for code symbols.  This option
   2466  1.1  mrg 	 is equivalent to the user asserting that the entire data
   2467  1.1  mrg 	 section is accessible from the GP.  */
   2468  1.1  mrg       return !SYMBOL_REF_FUNCTION_P (sym);
   2469  1.1  mrg 
   2470  1.1  mrg     case gpopt_all:
   2471  1.1  mrg       /* Use GP-relative addressing for everything, including code.
   2472  1.1  mrg 	 Effectively, the user has asserted that the entire program
   2473  1.1  mrg 	 fits within the 64K range of the GP offset.  */
   2474  1.1  mrg       return true;
   2475  1.1  mrg 
   2476  1.1  mrg     default:
   2477  1.1  mrg       /* We shouldn't get here.  */
   2478  1.1  mrg       return false;
   2479  1.1  mrg     }
   2480  1.1  mrg }
   2481  1.1  mrg 
   2482  1.1  mrg /* Likewise for r0-relative addressing.  */
   2483  1.1  mrg static bool
   2484  1.1  mrg nios2_symbol_ref_in_r0rel_data_p (rtx sym)
   2485  1.1  mrg {
   2486  1.1  mrg   tree decl;
   2487  1.1  mrg 
   2488  1.1  mrg   gcc_assert (GET_CODE (sym) == SYMBOL_REF);
   2489  1.1  mrg   decl = SYMBOL_REF_DECL (sym);
   2490  1.1  mrg 
   2491  1.1  mrg   /* TLS variables are not accessed through r0.  */
   2492  1.1  mrg   if (SYMBOL_REF_TLS_MODEL (sym) != 0)
   2493  1.1  mrg     return false;
   2494  1.1  mrg 
   2495  1.1  mrg   /* On Nios II R2, there is no r0-relative relocation that can be
   2496  1.1  mrg      used with "io" instructions.  So, if we are implicitly generating
   2497  1.1  mrg      those instructions, we cannot emit r0-relative accesses.  */
   2498  1.1  mrg   if (TARGET_ARCH_R2
   2499  1.1  mrg       && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
   2500  1.1  mrg     return false;
   2501  1.1  mrg 
   2502  1.1  mrg   /* If the user has explicitly placed the symbol in a r0rel section
   2503  1.1  mrg      via an attribute, generate r0-relative addressing.  */
   2504  1.1  mrg   if (decl && DECL_SECTION_NAME (decl))
   2505  1.1  mrg     return nios2_r0rel_section_name_p (DECL_SECTION_NAME (decl));
   2506  1.1  mrg   return false;
   2507  1.1  mrg }
   2508  1.1  mrg 
   2509  1.1  mrg /* Implement TARGET_SECTION_TYPE_FLAGS.  */
   2510  1.1  mrg 
   2511  1.1  mrg static unsigned int
   2512  1.1  mrg nios2_section_type_flags (tree decl, const char *name, int reloc)
   2513  1.1  mrg {
   2514  1.1  mrg   unsigned int flags;
   2515  1.1  mrg 
   2516  1.1  mrg   flags = default_section_type_flags (decl, name, reloc);
   2517  1.1  mrg 
   2518  1.1  mrg   if (nios2_small_section_name_p (name))
   2519  1.1  mrg     flags |= SECTION_SMALL;
   2520  1.1  mrg 
   2521  1.1  mrg   return flags;
   2522  1.1  mrg }
   2523  1.1  mrg 
   2524  1.1  mrg /* Return true if SYMBOL_REF X binds locally.  */
   2525  1.1  mrg 
   2526  1.1  mrg static bool
   2527  1.1  mrg nios2_symbol_binds_local_p (const_rtx x)
   2528  1.1  mrg {
   2529  1.1  mrg   return (SYMBOL_REF_DECL (x)
   2530  1.1  mrg 	  ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
   2531  1.1  mrg 	  : SYMBOL_REF_LOCAL_P (x));
   2532  1.1  mrg }
   2533  1.1  mrg 
   2534  1.1  mrg /* Position independent code related.  */
   2535  1.1  mrg 
   2536  1.1  mrg /* Emit code to load the PIC register.  */
   2537  1.1  mrg static void
   2538  1.1  mrg nios2_load_pic_register (void)
   2539  1.1  mrg {
   2540  1.1  mrg   rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
   2541  1.1  mrg 
   2542  1.1  mrg   emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp));
   2543  1.1  mrg   emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp));
   2544  1.1  mrg }
   2545  1.1  mrg 
   2546  1.1  mrg /* Generate a PIC address as a MEM rtx.  */
   2547  1.1  mrg static rtx
   2548  1.1  mrg nios2_load_pic_address (rtx sym, int unspec, rtx tmp)
   2549  1.1  mrg {
   2550  1.1  mrg   if (flag_pic == 2
   2551  1.1  mrg       && GET_CODE (sym) == SYMBOL_REF
   2552  1.1  mrg       && nios2_symbol_binds_local_p (sym))
   2553  1.1  mrg     /* Under -fPIC, generate a GOTOFF address for local symbols.  */
   2554  1.1  mrg     {
   2555  1.1  mrg       rtx offset = nios2_unspec_offset (sym, UNSPEC_PIC_GOTOFF_SYM);
   2556  1.1  mrg       crtl->uses_pic_offset_table = 1;
   2557  1.1  mrg       return nios2_large_got_address (offset, tmp);
   2558  1.1  mrg     }
   2559  1.1  mrg 
   2560  1.1  mrg   return gen_const_mem (Pmode, nios2_got_address (sym, unspec));
   2561  1.1  mrg }
   2562  1.1  mrg 
   2563  1.1  mrg /* Nonzero if the constant value X is a legitimate general operand
   2564  1.1  mrg    when generating PIC code.  It is given that flag_pic is on and
   2565  1.1  mrg    that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
   2566  1.1  mrg bool
   2567  1.1  mrg nios2_legitimate_pic_operand_p (rtx x)
   2568  1.1  mrg {
   2569  1.1  mrg   if (nios2_large_unspec_reloc_p (x))
   2570  1.1  mrg     return true;
   2571  1.1  mrg 
   2572  1.1  mrg   return ! (GET_CODE (x) == SYMBOL_REF
   2573  1.1  mrg 	    || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST);
   2574  1.1  mrg }
   2575  1.1  mrg 
   2576  1.1  mrg /* Return TRUE if X is a thread-local symbol.  */
   2577  1.1  mrg static bool
   2578  1.1  mrg nios2_tls_symbol_p (rtx x)
   2579  1.1  mrg {
   2580  1.1  mrg   return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF
   2581  1.1  mrg 	  && SYMBOL_REF_TLS_MODEL (x) != 0);
   2582  1.1  mrg }
   2583  1.1  mrg 
   2584  1.1  mrg /* Legitimize addresses that are CONSTANT_P expressions.  */
   2585  1.1  mrg static rtx
   2586  1.1  mrg nios2_legitimize_constant_address (rtx addr)
   2587  1.1  mrg {
   2588  1.1  mrg   rtx base, offset;
   2589  1.1  mrg   split_const (addr, &base, &offset);
   2590  1.1  mrg 
   2591  1.1  mrg   if (nios2_tls_symbol_p (base))
   2592  1.1  mrg     base = nios2_legitimize_tls_address (base);
   2593  1.1  mrg   else if (flag_pic)
   2594  1.1  mrg     base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
   2595  1.1  mrg   else if (!nios2_large_constant_allowed ()
   2596  1.1  mrg 	   && nios2_symbolic_constant_p (addr))
   2597  1.1  mrg     return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
   2598  1.1  mrg   else if (CONST_INT_P (addr))
   2599  1.1  mrg     {
   2600  1.1  mrg       HOST_WIDE_INT val = INTVAL (addr);
   2601  1.1  mrg       if (SMALL_INT (val))
   2602  1.1  mrg 	/* Use r0-relative addressing.  */
   2603  1.1  mrg 	return addr;
   2604  1.1  mrg       else if (!nios2_large_constant_allowed ())
   2605  1.1  mrg 	/* Split into high/lo pair.  */
   2606  1.1  mrg 	return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
   2607  1.1  mrg     }
   2608  1.1  mrg   else
   2609  1.1  mrg     return addr;
   2610  1.1  mrg 
   2611  1.1  mrg   if (offset != const0_rtx)
   2612  1.1  mrg     {
   2613  1.1  mrg       gcc_assert (can_create_pseudo_p ());
   2614  1.1  mrg       return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
   2615  1.1  mrg 			   (CONST_INT_P (offset)
   2616  1.1  mrg 			    ? (SMALL_INT (INTVAL (offset))
   2617  1.1  mrg 			       ? offset : force_reg (Pmode, offset))
   2618  1.1  mrg 			    : offset));
   2619  1.1  mrg     }
   2620  1.1  mrg   return base;
   2621  1.1  mrg }
   2622  1.1  mrg 
   2623  1.1  mrg /* Implement TARGET_LEGITIMIZE_ADDRESS.  */
   2624  1.1  mrg static rtx
   2625  1.1  mrg nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
   2626  1.1  mrg 			  machine_mode mode ATTRIBUTE_UNUSED)
   2627  1.1  mrg {
   2628  1.1  mrg   rtx op0, op1;
   2629  1.1  mrg 
   2630  1.1  mrg   if (CONSTANT_P (x))
   2631  1.1  mrg     return nios2_legitimize_constant_address (x);
   2632  1.1  mrg 
   2633  1.1  mrg   /* Remaining cases all involve something + a constant.  */
   2634  1.1  mrg   if (GET_CODE (x) != PLUS)
   2635  1.1  mrg     return x;
   2636  1.1  mrg 
   2637  1.1  mrg   op0 = XEXP (x, 0);
   2638  1.1  mrg   op1 = XEXP (x, 1);
   2639  1.1  mrg 
   2640  1.1  mrg   /* Target-independent code turns (exp + constant) into plain
   2641  1.1  mrg      register indirect.  Although subsequent optimization passes will
   2642  1.1  mrg      eventually sort that out, ivopts uses the unoptimized form for
   2643  1.1  mrg      computing its cost model, so we get better results by generating
   2644  1.1  mrg      the correct form from the start.  */
   2645  1.1  mrg   if (nios2_valid_addr_offset_p (op1))
   2646  1.1  mrg     return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
   2647  1.1  mrg 
   2648  1.1  mrg   /* We may need to split symbolic constants now.  */
   2649  1.1  mrg   else if (nios2_symbolic_constant_p (op1))
   2650  1.1  mrg     {
   2651  1.1  mrg       if (nios2_large_constant_allowed ())
   2652  1.1  mrg 	return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
   2653  1.1  mrg       else
   2654  1.1  mrg 	return nios2_split_plus_large_constant (op0, op1);
   2655  1.1  mrg     }
   2656  1.1  mrg 
   2657  1.1  mrg   /* For the TLS LE (Local Exec) model, the compiler may try to
   2658  1.1  mrg      combine constant offsets with unspec relocs, creating address RTXs
   2659  1.1  mrg      looking like this:
   2660  1.1  mrg      (plus:SI (reg:SI 23 r23)
   2661  1.1  mrg               (const:SI
   2662  1.1  mrg                 (plus:SI
   2663  1.1  mrg                   (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE)
   2664  1.1  mrg                   (const_int 48 [0x30]))))
   2665  1.1  mrg 
   2666  1.1  mrg      This usually happens when 'var' is a thread-local struct variable,
   2667  1.1  mrg      and access of a field in var causes the addend.
   2668  1.1  mrg 
   2669  1.1  mrg      We typically want this combining, so transform the above into this
   2670  1.1  mrg      form, which is allowed:
   2671  1.1  mrg      (plus:SI (reg:SI 23 r23)
   2672  1.1  mrg               (const:SI
   2673  1.1  mrg                 (unspec:SI
   2674  1.1  mrg                   [(const:SI
   2675  1.1  mrg                      (plus:SI (symbol_ref:SI ("var"))
   2676  1.1  mrg                               (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE)))
   2677  1.1  mrg 
   2678  1.1  mrg      Which will be output as '%tls_le(var+48)(r23)' in assembly.  */
   2679  1.1  mrg   else if (GET_CODE (op1) == CONST)
   2680  1.1  mrg     {
   2681  1.1  mrg       rtx unspec, offset;
   2682  1.1  mrg       split_const (op1, &unspec, &offset);
   2683  1.1  mrg       if (GET_CODE (unspec) == UNSPEC
   2684  1.1  mrg 	  && !nios2_large_offset_p (XINT (unspec, 1))
   2685  1.1  mrg 	  && offset != const0_rtx)
   2686  1.1  mrg 	{
   2687  1.1  mrg 	  rtx reg = force_reg (Pmode, op0);
   2688  1.1  mrg 	  unspec = copy_rtx (unspec);
   2689  1.1  mrg 	  XVECEXP (unspec, 0, 0)
   2690  1.1  mrg 	    = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset));
   2691  1.1  mrg 	  return gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec));
   2692  1.1  mrg 	}
   2693  1.1  mrg     }
   2694  1.1  mrg 
   2695  1.1  mrg   return x;
   2696  1.1  mrg }
   2697  1.1  mrg 
   2698  1.1  mrg static rtx
   2699  1.1  mrg nios2_delegitimize_address (rtx x)
   2700  1.1  mrg {
   2701  1.1  mrg   x = delegitimize_mem_from_attrs (x);
   2702  1.1  mrg 
   2703  1.1  mrg   if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
   2704  1.1  mrg     {
   2705  1.1  mrg       switch (XINT (XEXP (x, 0), 1))
   2706  1.1  mrg 	{
   2707  1.1  mrg 	case UNSPEC_PIC_SYM:
   2708  1.1  mrg 	case UNSPEC_PIC_CALL_SYM:
   2709  1.1  mrg 	case UNSPEC_PIC_GOTOFF_SYM:
   2710  1.1  mrg 	case UNSPEC_ADD_TLS_GD:
   2711  1.1  mrg 	case UNSPEC_ADD_TLS_LDM:
   2712  1.1  mrg 	case UNSPEC_LOAD_TLS_IE:
   2713  1.1  mrg 	case UNSPEC_ADD_TLS_LE:
   2714  1.1  mrg 	  x = XVECEXP (XEXP (x, 0), 0, 0);
   2715  1.1  mrg 	  gcc_assert (CONSTANT_P (x));
   2716  1.1  mrg 	  break;
   2717  1.1  mrg 	}
   2718  1.1  mrg     }
   2719  1.1  mrg   return x;
   2720  1.1  mrg }
   2721  1.1  mrg 
   2722  1.1  mrg /* Main expander function for RTL moves.  */
   2723  1.1  mrg bool
   2724  1.1  mrg nios2_emit_move_sequence (rtx *operands, machine_mode mode)
   2725  1.1  mrg {
   2726  1.1  mrg   rtx to = operands[0];
   2727  1.1  mrg   rtx from = operands[1];
   2728  1.1  mrg 
   2729  1.1  mrg   if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
   2730  1.1  mrg     {
   2731  1.1  mrg       gcc_assert (can_create_pseudo_p ());
   2732  1.1  mrg       from = copy_to_mode_reg (mode, from);
   2733  1.1  mrg     }
   2734  1.1  mrg 
   2735  1.1  mrg   if (CONSTANT_P (from))
   2736  1.1  mrg     {
   2737  1.1  mrg       if (CONST_INT_P (from))
   2738  1.1  mrg 	{
   2739  1.1  mrg 	  if (!SMALL_INT (INTVAL (from))
   2740  1.1  mrg 	      && !SMALL_INT_UNSIGNED (INTVAL (from))
   2741  1.1  mrg 	      && !UPPER16_INT (INTVAL (from)))
   2742  1.1  mrg 	    {
   2743  1.1  mrg 	      HOST_WIDE_INT high = (INTVAL (from) + 0x8000) & ~0xffff;
   2744  1.1  mrg 	      HOST_WIDE_INT low = INTVAL (from) & 0xffff;
   2745  1.1  mrg 	      emit_move_insn (to, gen_int_mode (high, SImode));
   2746  1.1  mrg 	      emit_insn (gen_add2_insn (to, gen_int_mode (low, HImode)));
   2747  1.1  mrg 	      set_unique_reg_note (get_last_insn (), REG_EQUAL,
   2748  1.1  mrg 				   copy_rtx (from));
   2749  1.1  mrg 	      return true;
   2750  1.1  mrg 	    }
   2751  1.1  mrg 	}
   2752  1.1  mrg       else if (gprel_constant_p (from) || r0rel_constant_p (from))
   2753  1.1  mrg 	/* Handled directly by movsi_internal as gp + offset
   2754  1.1  mrg 	   or r0 + offset.  */
   2755  1.1  mrg 	;
   2756  1.1  mrg       else if (nios2_large_constant_p (from))
   2757  1.1  mrg 	/* This case covers either a regular symbol reference or an UNSPEC
   2758  1.1  mrg 	   representing a 32-bit offset.  We split the former
   2759  1.1  mrg 	   only conditionally and the latter always.  */
   2760  1.1  mrg 	{
   2761  1.1  mrg 	  if (!nios2_large_constant_allowed ()
   2762  1.1  mrg 	      || nios2_large_unspec_reloc_p (from))
   2763  1.1  mrg 	    {
   2764  1.1  mrg 	      rtx lo = nios2_split_large_constant (from, to);
   2765  1.1  mrg 	      emit_insn (gen_rtx_SET (to, lo));
   2766  1.1  mrg 	      set_unique_reg_note (get_last_insn (), REG_EQUAL,
   2767  1.1  mrg 				   copy_rtx (operands[1]));
   2768  1.1  mrg 	      return true;
   2769  1.1  mrg 	    }
   2770  1.1  mrg 	}
   2771  1.1  mrg       else
   2772  1.1  mrg 	/* This is a TLS or PIC symbol.  */
   2773  1.1  mrg 	{
   2774  1.1  mrg 	  from = nios2_legitimize_constant_address (from);
   2775  1.1  mrg 	  if (CONSTANT_P (from))
   2776  1.1  mrg 	    {
   2777  1.1  mrg 	      emit_insn (gen_rtx_SET (to,
   2778  1.1  mrg 				      gen_rtx_HIGH (Pmode, copy_rtx (from))));
   2779  1.1  mrg 	      emit_insn (gen_rtx_SET (to, gen_rtx_LO_SUM (Pmode, to, from)));
   2780  1.1  mrg 	      set_unique_reg_note (get_last_insn (), REG_EQUAL,
   2781  1.1  mrg 				   copy_rtx (operands[1]));
   2782  1.1  mrg 	      return true;
   2783  1.1  mrg 	    }
   2784  1.1  mrg 	}
   2785  1.1  mrg     }
   2786  1.1  mrg 
   2787  1.1  mrg   operands[0] = to;
   2788  1.1  mrg   operands[1] = from;
   2789  1.1  mrg   return false;
   2790  1.1  mrg }
   2791  1.1  mrg 
   2792  1.1  mrg /* The function with address *ADDR is being called.  If the address
   2793  1.1  mrg    needs to be loaded from the GOT, emit the instruction to do so and
   2794  1.1  mrg    update *ADDR to point to the rtx for the loaded value.
   2795  1.1  mrg    If REG != NULL_RTX, it is used as the target/scratch register in the
   2796  1.1  mrg    GOT address calculation.  */
   2797  1.1  mrg void
   2798  1.1  mrg nios2_adjust_call_address (rtx *call_op, rtx reg)
   2799  1.1  mrg {
   2800  1.1  mrg   if (MEM_P (*call_op))
   2801  1.1  mrg     call_op = &XEXP (*call_op, 0);
   2802  1.1  mrg 
   2803  1.1  mrg   rtx addr = *call_op;
   2804  1.1  mrg   if (flag_pic && CONSTANT_P (addr))
   2805  1.1  mrg     {
   2806  1.1  mrg       rtx tmp = reg ? reg : NULL_RTX;
   2807  1.1  mrg       if (!reg)
   2808  1.1  mrg 	reg = gen_reg_rtx (Pmode);
   2809  1.1  mrg       addr = nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM, tmp);
   2810  1.1  mrg       emit_insn (gen_rtx_SET (reg, addr));
   2811  1.1  mrg       *call_op = reg;
   2812  1.1  mrg     }
   2813  1.1  mrg }
   2814  1.1  mrg 
   2815  1.1  mrg 
   2816  1.1  mrg /* Output assembly language related definitions.  */
   2818  1.1  mrg 
   2819  1.1  mrg /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P.  */
   2820  1.1  mrg static bool
   2821  1.1  mrg nios2_print_operand_punct_valid_p (unsigned char code)
   2822  1.1  mrg {
   2823  1.1  mrg   return (code == '.' || code == '!');
   2824  1.1  mrg }
   2825  1.1  mrg 
   2826  1.1  mrg 
   2827  1.1  mrg /* Print the operand OP to file stream FILE modified by LETTER.
   2828  1.1  mrg    LETTER can be one of:
   2829  1.1  mrg 
   2830  1.1  mrg      i: print i/hi/ui suffixes (used for mov instruction variants),
   2831  1.1  mrg         when OP is the appropriate immediate operand.
   2832  1.1  mrg 
   2833  1.1  mrg      u: like 'i', except without "ui" suffix case (used for cmpgeu/cmpltu)
   2834  1.1  mrg 
   2835  1.1  mrg      o: print "io" if OP needs volatile access (due to TARGET_BYPASS_CACHE
   2836  1.1  mrg         or TARGET_BYPASS_CACHE_VOLATILE).
   2837  1.1  mrg 
   2838  1.1  mrg      x: print i/hi/ci/chi suffixes for the and instruction,
   2839  1.1  mrg         when OP is the appropriate immediate operand.
   2840  1.1  mrg 
   2841  1.1  mrg      z: prints the third register immediate operand in assembly
   2842  1.1  mrg         instructions.  Outputs const0_rtx as the 'zero' register
   2843  1.1  mrg 	instead of '0'.
   2844  1.1  mrg 
   2845  1.1  mrg      y: same as 'z', but for specifically for logical instructions,
   2846  1.1  mrg         where the processing for immediates are slightly different.
   2847  1.1  mrg 
   2848  1.1  mrg      H: for %hiadj
   2849  1.1  mrg      L: for %lo
   2850  1.1  mrg      D: for the upper 32-bits of a 64-bit double value
   2851  1.1  mrg      R: prints reverse condition.
   2852  1.1  mrg      A: prints (reg) operand for ld[s]ex and st[s]ex.
   2853  1.1  mrg 
   2854  1.1  mrg      .: print .n suffix for 16-bit instructions.
   2855  1.1  mrg      !: print r.n suffix for 16-bit instructions.  Used for jmpr.n.
   2856  1.1  mrg */
   2857  1.1  mrg static void
   2858  1.1  mrg nios2_print_operand (FILE *file, rtx op, int letter)
   2859  1.1  mrg {
   2860  1.1  mrg 
   2861  1.1  mrg   /* First take care of the format letters that just insert a string
   2862  1.1  mrg      into the output stream.  */
   2863  1.1  mrg   switch (letter)
   2864  1.1  mrg     {
   2865  1.1  mrg     case '.':
   2866  1.1  mrg       if (current_output_insn && get_attr_length (current_output_insn) == 2)
   2867  1.1  mrg 	fprintf (file, ".n");
   2868  1.1  mrg       return;
   2869  1.1  mrg 
   2870  1.1  mrg     case '!':
   2871  1.1  mrg       if (current_output_insn && get_attr_length (current_output_insn) == 2)
   2872  1.1  mrg 	fprintf (file, "r.n");
   2873  1.1  mrg       return;
   2874  1.1  mrg 
   2875  1.1  mrg     case 'x':
   2876  1.1  mrg       if (CONST_INT_P (op))
   2877  1.1  mrg 	{
   2878  1.1  mrg 	  HOST_WIDE_INT val = INTVAL (op);
   2879  1.1  mrg 	  HOST_WIDE_INT low = val & 0xffff;
   2880  1.1  mrg 	  HOST_WIDE_INT high = (val >> 16) & 0xffff;
   2881  1.1  mrg 
   2882  1.1  mrg 	  if (val != 0)
   2883  1.1  mrg 	    {
   2884  1.1  mrg 	      if (high != 0)
   2885  1.1  mrg 		{
   2886  1.1  mrg 		  if (low != 0)
   2887  1.1  mrg 		    {
   2888  1.1  mrg 		      gcc_assert (TARGET_ARCH_R2);
   2889  1.1  mrg 		      if (high == 0xffff)
   2890  1.1  mrg 			fprintf (file, "c");
   2891  1.1  mrg 		      else if (low == 0xffff)
   2892  1.1  mrg 			fprintf (file, "ch");
   2893  1.1  mrg 		      else
   2894  1.1  mrg 			gcc_unreachable ();
   2895  1.1  mrg 		    }
   2896  1.1  mrg 		  else
   2897  1.1  mrg 		    fprintf (file, "h");
   2898  1.1  mrg 		}
   2899  1.1  mrg 	      fprintf (file, "i");
   2900  1.1  mrg 	    }
   2901  1.1  mrg 	}
   2902  1.1  mrg       return;
   2903  1.1  mrg 
   2904  1.1  mrg     case 'u':
   2905  1.1  mrg     case 'i':
   2906  1.1  mrg       if (CONST_INT_P (op))
   2907  1.1  mrg 	{
   2908  1.1  mrg 	  HOST_WIDE_INT val = INTVAL (op);
   2909  1.1  mrg 	  HOST_WIDE_INT low = val & 0xffff;
   2910  1.1  mrg 	  HOST_WIDE_INT high = (val >> 16) & 0xffff;
   2911  1.1  mrg 	  if (val != 0)
   2912  1.1  mrg 	    {
   2913  1.1  mrg 	      if (low == 0 && high != 0)
   2914  1.1  mrg 		fprintf (file, "h");
   2915  1.1  mrg 	      else if (high == 0 && (low & 0x8000) != 0 && letter != 'u')
   2916  1.1  mrg 		fprintf (file, "u");
   2917  1.1  mrg 	    }
   2918  1.1  mrg 	}
   2919  1.1  mrg       if (CONSTANT_P (op) && op != const0_rtx)
   2920  1.1  mrg         fprintf (file, "i");
   2921  1.1  mrg       return;
   2922  1.1  mrg 
   2923  1.1  mrg     case 'o':
   2924  1.1  mrg       if (GET_CODE (op) == MEM
   2925  1.1  mrg 	  && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
   2926  1.1  mrg 	      || TARGET_BYPASS_CACHE))
   2927  1.1  mrg 	{
   2928  1.1  mrg 	  gcc_assert (current_output_insn
   2929  1.1  mrg 		      && get_attr_length (current_output_insn) == 4);
   2930  1.1  mrg 	  fprintf (file, "io");
   2931  1.1  mrg 	}
   2932  1.1  mrg       return;
   2933  1.1  mrg 
   2934  1.1  mrg     default:
   2935  1.1  mrg       break;
   2936  1.1  mrg     }
   2937  1.1  mrg 
   2938  1.1  mrg   /* Handle comparison operator names.  */
   2939  1.1  mrg   if (comparison_operator (op, VOIDmode))
   2940  1.1  mrg     {
   2941  1.1  mrg       enum rtx_code cond = GET_CODE (op);
   2942  1.1  mrg       if (letter == 0)
   2943  1.1  mrg 	{
   2944  1.1  mrg 	  fprintf (file, "%s", GET_RTX_NAME (cond));
   2945  1.1  mrg 	  return;
   2946  1.1  mrg 	}
   2947  1.1  mrg       if (letter == 'R')
   2948  1.1  mrg 	{
   2949  1.1  mrg 	  fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
   2950  1.1  mrg 	  return;
   2951  1.1  mrg 	}
   2952  1.1  mrg     }
   2953  1.1  mrg 
   2954  1.1  mrg   /* Now handle the cases where we actually need to format an operand.  */
   2955  1.1  mrg   switch (GET_CODE (op))
   2956  1.1  mrg     {
   2957  1.1  mrg     case REG:
   2958  1.1  mrg       if (letter == 0 || letter == 'z' || letter == 'y')
   2959  1.1  mrg         {
   2960  1.1  mrg           fprintf (file, "%s", reg_names[REGNO (op)]);
   2961  1.1  mrg           return;
   2962  1.1  mrg         }
   2963  1.1  mrg       else if (letter == 'D')
   2964  1.1  mrg         {
   2965  1.1  mrg           fprintf (file, "%s", reg_names[REGNO (op)+1]);
   2966  1.1  mrg           return;
   2967  1.1  mrg         }
   2968  1.1  mrg       break;
   2969  1.1  mrg 
   2970  1.1  mrg     case CONST_INT:
   2971  1.1  mrg       {
   2972  1.1  mrg 	rtx int_rtx = op;
   2973  1.1  mrg 	HOST_WIDE_INT val = INTVAL (int_rtx);
   2974  1.1  mrg 	HOST_WIDE_INT low = val & 0xffff;
   2975  1.1  mrg 	HOST_WIDE_INT high = (val >> 16) & 0xffff;
   2976  1.1  mrg 
   2977  1.1  mrg 	if (letter == 'y')
   2978  1.1  mrg 	  {
   2979  1.1  mrg 	    if (val == 0)
   2980  1.1  mrg 	      fprintf (file, "zero");
   2981  1.1  mrg 	    else
   2982  1.1  mrg 	      {
   2983  1.1  mrg 		if (high != 0)
   2984  1.1  mrg 		  {
   2985  1.1  mrg 		    if (low != 0)
   2986  1.1  mrg 		      {
   2987  1.1  mrg 			gcc_assert (TARGET_ARCH_R2);
   2988  1.1  mrg 			if (high == 0xffff)
   2989  1.1  mrg 			  /* andci.  */
   2990  1.1  mrg 			  int_rtx = gen_int_mode (low, SImode);
   2991  1.1  mrg 			else if (low == 0xffff)
   2992  1.1  mrg 			  /* andchi.  */
   2993  1.1  mrg 			  int_rtx = gen_int_mode (high, SImode);
   2994  1.1  mrg 			else
   2995  1.1  mrg 			  gcc_unreachable ();
   2996  1.1  mrg 		      }
   2997  1.1  mrg 		    else
   2998  1.1  mrg 		      /* andhi.  */
   2999  1.1  mrg 		      int_rtx = gen_int_mode (high, SImode);
   3000  1.1  mrg 		  }
   3001  1.1  mrg 		else
   3002  1.1  mrg 		  /* andi.  */
   3003  1.1  mrg 		  int_rtx = gen_int_mode (low, SImode);
   3004  1.1  mrg 		output_addr_const (file, int_rtx);
   3005  1.1  mrg 	      }
   3006  1.1  mrg 	    return;
   3007  1.1  mrg 	  }
   3008  1.1  mrg 	else if (letter == 'z')
   3009  1.1  mrg 	  {
   3010  1.1  mrg 	    if (val == 0)
   3011  1.1  mrg 	      fprintf (file, "zero");
   3012  1.1  mrg 	    else
   3013  1.1  mrg 	      {
   3014  1.1  mrg 		if (low == 0 && high != 0)
   3015  1.1  mrg 		  int_rtx = gen_int_mode (high, SImode);
   3016  1.1  mrg 		else if (low != 0)
   3017  1.1  mrg 		  {
   3018  1.1  mrg 		    gcc_assert (high == 0 || high == 0xffff);
   3019  1.1  mrg 		    int_rtx = gen_int_mode (low, high == 0 ? SImode : HImode);
   3020  1.1  mrg 		  }
   3021  1.1  mrg 		else
   3022  1.1  mrg 		  gcc_unreachable ();
   3023  1.1  mrg 		output_addr_const (file, int_rtx);
   3024  1.1  mrg 	      }
   3025  1.1  mrg 	    return;
   3026  1.1  mrg 	  }
   3027  1.1  mrg       }
   3028  1.1  mrg 
   3029  1.1  mrg       /* Else, fall through.  */
   3030  1.1  mrg 
   3031  1.1  mrg     case CONST:
   3032  1.1  mrg     case LABEL_REF:
   3033  1.1  mrg     case SYMBOL_REF:
   3034  1.1  mrg     case CONST_DOUBLE:
   3035  1.1  mrg       if (letter == 0 || letter == 'z')
   3036  1.1  mrg         {
   3037  1.1  mrg           output_addr_const (file, op);
   3038  1.1  mrg           return;
   3039  1.1  mrg         }
   3040  1.1  mrg       else if (letter == 'H' || letter == 'L')
   3041  1.1  mrg 	{
   3042  1.1  mrg 	  fprintf (file, "%%");
   3043  1.1  mrg 	  if (GET_CODE (op) == CONST
   3044  1.1  mrg 	      && GET_CODE (XEXP (op, 0)) == UNSPEC)
   3045  1.1  mrg 	    {
   3046  1.1  mrg 	      rtx unspec = XEXP (op, 0);
   3047  1.1  mrg 	      int unspec_reloc = XINT (unspec, 1);
   3048  1.1  mrg 	      gcc_assert (nios2_large_offset_p (unspec_reloc));
   3049  1.1  mrg 	      fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc));
   3050  1.1  mrg 	      op = XVECEXP (unspec, 0, 0);
   3051  1.1  mrg 	    }
   3052  1.1  mrg           fprintf (file, letter == 'H' ? "hiadj(" : "lo(");
   3053  1.1  mrg           output_addr_const (file, op);
   3054  1.1  mrg           fprintf (file, ")");
   3055  1.1  mrg           return;
   3056  1.1  mrg 	}
   3057  1.1  mrg       break;
   3058  1.1  mrg 
   3059  1.1  mrg     case SUBREG:
   3060  1.1  mrg     case MEM:
   3061  1.1  mrg       if (letter == 'A')
   3062  1.1  mrg 	{
   3063  1.1  mrg 	  /* Address of '(reg)' form, with no index.  */
   3064  1.1  mrg 	  fprintf (file, "(%s)", reg_names[REGNO (XEXP (op, 0))]);
   3065  1.1  mrg 	  return;
   3066  1.1  mrg 	}
   3067  1.1  mrg       if (letter == 0)
   3068  1.1  mrg         {
   3069  1.1  mrg           output_address (VOIDmode, op);
   3070  1.1  mrg           return;
   3071  1.1  mrg         }
   3072  1.1  mrg       break;
   3073  1.1  mrg 
   3074  1.1  mrg     case CODE_LABEL:
   3075  1.1  mrg       if (letter == 0)
   3076  1.1  mrg         {
   3077  1.1  mrg           output_addr_const (file, op);
   3078  1.1  mrg           return;
   3079  1.1  mrg         }
   3080  1.1  mrg       break;
   3081  1.1  mrg 
   3082  1.1  mrg     default:
   3083  1.1  mrg       break;
   3084  1.1  mrg     }
   3085  1.1  mrg 
   3086  1.1  mrg   debug_rtx (op);
   3087  1.1  mrg   output_operand_lossage ("Unsupported operand for code '%c'", letter);
   3088  1.1  mrg   gcc_unreachable ();
   3089  1.1  mrg }
   3090  1.1  mrg 
   3091  1.1  mrg /* Return true if this is a GP-relative accessible reference.  */
   3092  1.1  mrg bool
   3093  1.1  mrg gprel_constant_p (rtx op)
   3094  1.1  mrg {
   3095  1.1  mrg   if (GET_CODE (op) == SYMBOL_REF
   3096  1.1  mrg       && nios2_symbol_ref_in_small_data_p (op))
   3097  1.1  mrg     return true;
   3098  1.1  mrg   else if (GET_CODE (op) == CONST
   3099  1.1  mrg            && GET_CODE (XEXP (op, 0)) == PLUS)
   3100  1.1  mrg     return gprel_constant_p (XEXP (XEXP (op, 0), 0));
   3101  1.1  mrg 
   3102  1.1  mrg   return false;
   3103  1.1  mrg }
   3104  1.1  mrg 
   3105  1.1  mrg /* Likewise if this is a zero-relative accessible reference.  */
   3106  1.1  mrg bool
   3107  1.1  mrg r0rel_constant_p (rtx op)
   3108  1.1  mrg {
   3109  1.1  mrg   if (GET_CODE (op) == SYMBOL_REF
   3110  1.1  mrg       && nios2_symbol_ref_in_r0rel_data_p (op))
   3111  1.1  mrg     return true;
   3112  1.1  mrg   else if (GET_CODE (op) == CONST
   3113  1.1  mrg            && GET_CODE (XEXP (op, 0)) == PLUS)
   3114  1.1  mrg     return r0rel_constant_p (XEXP (XEXP (op, 0), 0));
   3115  1.1  mrg   else if (GET_CODE (op) == CONST_INT
   3116  1.1  mrg 	   && SMALL_INT (INTVAL (op)))
   3117  1.1  mrg     return true;
   3118  1.1  mrg 
   3119  1.1  mrg   return false;
   3120  1.1  mrg }
   3121  1.1  mrg 
   3122  1.1  mrg /* Return the name string for a supported unspec reloc offset.  */
   3123  1.1  mrg static const char *
   3124  1.1  mrg nios2_unspec_reloc_name (int unspec)
   3125  1.1  mrg {
   3126  1.1  mrg   switch (unspec)
   3127  1.1  mrg     {
   3128  1.1  mrg     case UNSPEC_PIC_SYM:
   3129  1.1  mrg       return "got";
   3130  1.1  mrg     case UNSPEC_PIC_CALL_SYM:
   3131  1.1  mrg       return "call";
   3132  1.1  mrg     case UNSPEC_PIC_GOTOFF_SYM:
   3133  1.1  mrg       return "gotoff";
   3134  1.1  mrg     case UNSPEC_LOAD_TLS_IE:
   3135  1.1  mrg       return "tls_ie";
   3136  1.1  mrg     case UNSPEC_ADD_TLS_LE:
   3137  1.1  mrg       return "tls_le";
   3138  1.1  mrg     case UNSPEC_ADD_TLS_GD:
   3139  1.1  mrg       return "tls_gd";
   3140  1.1  mrg     case UNSPEC_ADD_TLS_LDM:
   3141  1.1  mrg       return "tls_ldm";
   3142  1.1  mrg     case UNSPEC_ADD_TLS_LDO:
   3143  1.1  mrg       return "tls_ldo";
   3144  1.1  mrg     default:
   3145  1.1  mrg       return NULL;
   3146  1.1  mrg     }
   3147  1.1  mrg }
   3148  1.1  mrg 
   3149  1.1  mrg /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA.  */
   3150  1.1  mrg static bool
   3151  1.1  mrg nios2_output_addr_const_extra (FILE *file, rtx op)
   3152  1.1  mrg {
   3153  1.1  mrg   const char *name;
   3154  1.1  mrg   gcc_assert (GET_CODE (op) == UNSPEC);
   3155  1.1  mrg 
   3156  1.1  mrg   /* Support for printing out const unspec relocations.  */
   3157  1.1  mrg   name = nios2_unspec_reloc_name (XINT (op, 1));
   3158  1.1  mrg   if (name)
   3159  1.1  mrg     {
   3160  1.1  mrg       fprintf (file, "%%%s(", name);
   3161  1.1  mrg       output_addr_const (file, XVECEXP (op, 0, 0));
   3162  1.1  mrg       fprintf (file, ")");
   3163  1.1  mrg       return true;
   3164  1.1  mrg     }
   3165  1.1  mrg   return false;
   3166  1.1  mrg }
   3167  1.1  mrg 
   3168  1.1  mrg /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
   3169  1.1  mrg static void
   3170  1.1  mrg nios2_print_operand_address (FILE *file, machine_mode mode, rtx op)
   3171  1.1  mrg {
   3172  1.1  mrg   switch (GET_CODE (op))
   3173  1.1  mrg     {
   3174  1.1  mrg     case CONST:
   3175  1.1  mrg     case CONST_INT:
   3176  1.1  mrg     case LABEL_REF:
   3177  1.1  mrg     case CONST_DOUBLE:
   3178  1.1  mrg     case SYMBOL_REF:
   3179  1.1  mrg       if (gprel_constant_p (op))
   3180  1.1  mrg         {
   3181  1.1  mrg           fprintf (file, "%%gprel(");
   3182  1.1  mrg           output_addr_const (file, op);
   3183  1.1  mrg           fprintf (file, ")(%s)", reg_names[GP_REGNO]);
   3184  1.1  mrg           return;
   3185  1.1  mrg         }
   3186  1.1  mrg       else if (r0rel_constant_p (op))
   3187  1.1  mrg         {
   3188  1.1  mrg 	  if (CONST_INT_P (op))
   3189  1.1  mrg 	    {
   3190  1.1  mrg 	      output_addr_const (file, op);
   3191  1.1  mrg 	      fprintf (file, "(r0)");
   3192  1.1  mrg 	      return;
   3193  1.1  mrg 	    }
   3194  1.1  mrg 	  else
   3195  1.1  mrg 	    {
   3196  1.1  mrg 	      fprintf (file, "%%lo(");
   3197  1.1  mrg 	      output_addr_const (file, op);
   3198  1.1  mrg 	      fprintf (file, ")(r0)");
   3199  1.1  mrg 	      return;
   3200  1.1  mrg 	    }
   3201  1.1  mrg 	}
   3202  1.1  mrg       break;
   3203  1.1  mrg 
   3204  1.1  mrg     case PLUS:
   3205  1.1  mrg       {
   3206  1.1  mrg         rtx op0 = XEXP (op, 0);
   3207  1.1  mrg         rtx op1 = XEXP (op, 1);
   3208  1.1  mrg 
   3209  1.1  mrg         if (REG_P (op0) && CONSTANT_P (op1))
   3210  1.1  mrg           {
   3211  1.1  mrg             output_addr_const (file, op1);
   3212  1.1  mrg             fprintf (file, "(%s)", reg_names[REGNO (op0)]);
   3213  1.1  mrg             return;
   3214  1.1  mrg           }
   3215  1.1  mrg         else if (REG_P (op1) && CONSTANT_P (op0))
   3216  1.1  mrg           {
   3217  1.1  mrg             output_addr_const (file, op0);
   3218  1.1  mrg             fprintf (file, "(%s)", reg_names[REGNO (op1)]);
   3219  1.1  mrg             return;
   3220  1.1  mrg           }
   3221  1.1  mrg       }
   3222  1.1  mrg       break;
   3223  1.1  mrg 
   3224  1.1  mrg     case LO_SUM:
   3225  1.1  mrg       {
   3226  1.1  mrg         rtx op0 = XEXP (op, 0);
   3227  1.1  mrg         rtx op1 = XEXP (op, 1);
   3228  1.1  mrg 
   3229  1.1  mrg 	if (REG_P (op0) && CONSTANT_P (op1))
   3230  1.1  mrg 	  {
   3231  1.1  mrg 	    nios2_print_operand (file, op1, 'L');
   3232  1.1  mrg 	    fprintf (file, "(%s)", reg_names[REGNO (op0)]);
   3233  1.1  mrg 	    return;
   3234  1.1  mrg 	  }
   3235  1.1  mrg       }
   3236  1.1  mrg       break;
   3237  1.1  mrg 
   3238  1.1  mrg     case REG:
   3239  1.1  mrg       fprintf (file, "0(%s)", reg_names[REGNO (op)]);
   3240  1.1  mrg       return;
   3241  1.1  mrg 
   3242  1.1  mrg     case MEM:
   3243  1.1  mrg       {
   3244  1.1  mrg         rtx base = XEXP (op, 0);
   3245  1.1  mrg         nios2_print_operand_address (file, mode, base);
   3246  1.1  mrg         return;
   3247  1.1  mrg       }
   3248  1.1  mrg     default:
   3249  1.1  mrg       break;
   3250  1.1  mrg     }
   3251  1.1  mrg 
   3252  1.1  mrg   fprintf (stderr, "Missing way to print address\n");
   3253  1.1  mrg   debug_rtx (op);
   3254  1.1  mrg   gcc_unreachable ();
   3255  1.1  mrg }
   3256  1.1  mrg 
   3257  1.1  mrg /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL.  */
   3258  1.1  mrg static void
   3259  1.1  mrg nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
   3260  1.1  mrg {
   3261  1.1  mrg   gcc_assert (size == 4);
   3262  1.1  mrg   fprintf (file, "\t.4byte\t%%tls_ldo(");
   3263  1.1  mrg   output_addr_const (file, x);
   3264  1.1  mrg   fprintf (file, ")");
   3265  1.1  mrg }
   3266  1.1  mrg 
   3267  1.1  mrg /* Implemet TARGET_ASM_FILE_END.  */
   3268  1.1  mrg 
   3269  1.1  mrg static void
   3270  1.1  mrg nios2_asm_file_end (void)
   3271  1.1  mrg {
   3272  1.1  mrg   /* The Nios II Linux stack is mapped non-executable by default, so add a
   3273  1.1  mrg      .note.GNU-stack section for switching to executable stacks only when
   3274  1.1  mrg      trampolines are generated.  */
   3275  1.1  mrg   if (TARGET_LINUX_ABI && trampolines_created)
   3276  1.1  mrg     file_end_indicate_exec_stack ();
   3277  1.1  mrg }
   3278  1.1  mrg 
   3279  1.1  mrg /* Implement TARGET_ASM_FUNCTION_PROLOGUE.  */
   3280  1.1  mrg static void
   3281  1.1  mrg nios2_asm_function_prologue (FILE *file)
   3282  1.1  mrg {
   3283  1.1  mrg   if (flag_verbose_asm || flag_debug_asm)
   3284  1.1  mrg     {
   3285  1.1  mrg       nios2_compute_frame_layout ();
   3286  1.1  mrg       nios2_dump_frame_layout (file);
   3287  1.1  mrg     }
   3288  1.1  mrg }
   3289  1.1  mrg 
   3290  1.1  mrg /* Emit assembly of custom FPU instructions.  */
   3291  1.1  mrg const char *
   3292  1.1  mrg nios2_fpu_insn_asm (enum n2fpu_code code)
   3293  1.1  mrg {
   3294  1.1  mrg   static char buf[256];
   3295  1.1  mrg   const char *op1, *op2, *op3;
   3296  1.1  mrg   int ln = 256, n = 0;
   3297  1.1  mrg 
   3298  1.1  mrg   int N = N2FPU_N (code);
   3299  1.1  mrg   int num_operands = N2FPU (code).num_operands;
   3300  1.1  mrg   const char *insn_name = N2FPU_NAME (code);
   3301  1.1  mrg   tree ftype = nios2_ftype (N2FPU_FTCODE (code));
   3302  1.1  mrg   machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
   3303  1.1  mrg   machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
   3304  1.1  mrg 
   3305  1.1  mrg   /* Prepare X register for DF input operands.  */
   3306  1.1  mrg   if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
   3307  1.1  mrg     n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
   3308  1.1  mrg 		  N2FPU_N (n2fpu_fwrx));
   3309  1.1  mrg 
   3310  1.1  mrg   if (src_mode == SFmode)
   3311  1.1  mrg     {
   3312  1.1  mrg       if (dst_mode == VOIDmode)
   3313  1.1  mrg 	{
   3314  1.1  mrg 	  /* The fwry case.  */
   3315  1.1  mrg 	  op1 = op3 = "zero";
   3316  1.1  mrg 	  op2 = "%0";
   3317  1.1  mrg 	  num_operands -= 1;
   3318  1.1  mrg 	}
   3319  1.1  mrg       else
   3320  1.1  mrg 	{
   3321  1.1  mrg 	  op1 = (dst_mode == DFmode ? "%D0" : "%0");
   3322  1.1  mrg 	  op2 = "%1";
   3323  1.1  mrg 	  op3 = (num_operands == 2 ? "zero" : "%2");
   3324  1.1  mrg 	}
   3325  1.1  mrg     }
   3326  1.1  mrg   else if (src_mode == DFmode)
   3327  1.1  mrg     {
   3328  1.1  mrg       if (dst_mode == VOIDmode)
   3329  1.1  mrg 	{
   3330  1.1  mrg 	  /* The fwrx case.  */
   3331  1.1  mrg 	  op1 = "zero";
   3332  1.1  mrg 	  op2 = "%0";
   3333  1.1  mrg 	  op3 = "%D0";
   3334  1.1  mrg 	  num_operands -= 1;
   3335  1.1  mrg 	}
   3336  1.1  mrg       else
   3337  1.1  mrg 	{
   3338  1.1  mrg 	  op1 = (dst_mode == DFmode ? "%D0" : "%0");
   3339  1.1  mrg 	  op2 = (num_operands == 2 ? "%1" : "%2");
   3340  1.1  mrg 	  op3 = (num_operands == 2 ? "%D1" : "%D2");
   3341  1.1  mrg 	}
   3342  1.1  mrg     }
   3343  1.1  mrg   else if (src_mode == VOIDmode)
   3344  1.1  mrg     {
   3345  1.1  mrg       /* frdxlo, frdxhi, frdy cases.  */
   3346  1.1  mrg       gcc_assert (dst_mode == SFmode);
   3347  1.1  mrg       op1 = "%0";
   3348  1.1  mrg       op2 = op3 = "zero";
   3349  1.1  mrg     }
   3350  1.1  mrg   else if (src_mode == SImode)
   3351  1.1  mrg     {
   3352  1.1  mrg       /* Conversion operators.  */
   3353  1.1  mrg       gcc_assert (num_operands == 2);
   3354  1.1  mrg       op1 = (dst_mode == DFmode ? "%D0" : "%0");
   3355  1.1  mrg       op2 = "%1";
   3356  1.1  mrg       op3 = "zero";
   3357  1.1  mrg     }
   3358  1.1  mrg   else
   3359  1.1  mrg     gcc_unreachable ();
   3360  1.1  mrg 
   3361  1.1  mrg   /* Main instruction string.  */
   3362  1.1  mrg   n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
   3363  1.1  mrg 		 N, op1, op2, op3, insn_name,
   3364  1.1  mrg 		 (num_operands >= 2 ? ", %1" : ""),
   3365  1.1  mrg 		 (num_operands == 3 ? ", %2" : ""));
   3366  1.1  mrg 
   3367  1.1  mrg   /* Extraction of Y register for DF results.  */
   3368  1.1  mrg   if (dst_mode == DFmode)
   3369  1.1  mrg     snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
   3370  1.1  mrg 	      N2FPU_N (n2fpu_frdy));
   3371  1.1  mrg   return buf;
   3372  1.1  mrg }
   3373  1.1  mrg 
   3374  1.1  mrg 
   3375  1.1  mrg 
   3377  1.1  mrg /* Function argument related.  */
   3378  1.1  mrg 
   3379  1.1  mrg /* Define where to put the arguments to a function.  Value is zero to
   3380  1.1  mrg    push the argument on the stack, or a hard register in which to
   3381  1.1  mrg    store the argument.
   3382  1.1  mrg 
   3383  1.1  mrg    CUM is a variable of type CUMULATIVE_ARGS which gives info about
   3384  1.1  mrg    the preceding args and about the function being called.
   3385  1.1  mrg    ARG is a description of the argument.  */
   3386  1.1  mrg 
   3387  1.1  mrg static rtx
   3388  1.1  mrg nios2_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
   3389  1.1  mrg {
   3390  1.1  mrg   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   3391  1.1  mrg   rtx return_rtx = NULL_RTX;
   3392  1.1  mrg 
   3393  1.1  mrg   if (cum->regs_used < NUM_ARG_REGS)
   3394  1.1  mrg     return_rtx = gen_rtx_REG (arg.mode, FIRST_ARG_REGNO + cum->regs_used);
   3395  1.1  mrg 
   3396  1.1  mrg   return return_rtx;
   3397  1.1  mrg }
   3398  1.1  mrg 
   3399  1.1  mrg /* Return number of bytes, at the beginning of the argument, that must be
   3400  1.1  mrg    put in registers.  0 is the argument is entirely in registers or entirely
   3401  1.1  mrg    in memory.  */
   3402  1.1  mrg 
   3403  1.1  mrg static int
   3404  1.1  mrg nios2_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
   3405  1.1  mrg {
   3406  1.1  mrg   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   3407  1.1  mrg   HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
   3408  1.1  mrg   gcc_assert (param_size >= 0);
   3409  1.1  mrg 
   3410  1.1  mrg   /* Convert to words (round up).  */
   3411  1.1  mrg   param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
   3412  1.1  mrg 
   3413  1.1  mrg   if (cum->regs_used < NUM_ARG_REGS
   3414  1.1  mrg       && cum->regs_used + param_size > NUM_ARG_REGS)
   3415  1.1  mrg     return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
   3416  1.1  mrg 
   3417  1.1  mrg   return 0;
   3418  1.1  mrg }
   3419  1.1  mrg 
   3420  1.1  mrg /* Update the data in CUM to advance over argument ARG.  */
   3421  1.1  mrg 
   3422  1.1  mrg static void
   3423  1.1  mrg nios2_function_arg_advance (cumulative_args_t cum_v,
   3424  1.1  mrg 			    const function_arg_info &arg)
   3425  1.1  mrg {
   3426  1.1  mrg   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   3427  1.1  mrg   HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
   3428  1.1  mrg   gcc_assert (param_size >= 0);
   3429  1.1  mrg 
   3430  1.1  mrg   /* Convert to words (round up).  */
   3431  1.1  mrg   param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
   3432  1.1  mrg 
   3433  1.1  mrg   if (cum->regs_used + param_size > NUM_ARG_REGS)
   3434  1.1  mrg     cum->regs_used = NUM_ARG_REGS;
   3435  1.1  mrg   else
   3436  1.1  mrg     cum->regs_used += param_size;
   3437  1.1  mrg }
   3438  1.1  mrg 
   3439  1.1  mrg static pad_direction
   3440  1.1  mrg nios2_function_arg_padding (machine_mode mode, const_tree type)
   3441  1.1  mrg {
   3442  1.1  mrg   /* On little-endian targets, the first byte of every stack argument
   3443  1.1  mrg      is passed in the first byte of the stack slot.  */
   3444  1.1  mrg   if (!BYTES_BIG_ENDIAN)
   3445  1.1  mrg     return PAD_UPWARD;
   3446  1.1  mrg 
   3447  1.1  mrg   /* Otherwise, integral types are padded downward: the last byte of a
   3448  1.1  mrg      stack argument is passed in the last byte of the stack slot.  */
   3449  1.1  mrg   if (type != 0
   3450  1.1  mrg       ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
   3451  1.1  mrg       : GET_MODE_CLASS (mode) == MODE_INT)
   3452  1.1  mrg     return PAD_DOWNWARD;
   3453  1.1  mrg 
   3454  1.1  mrg   /* Arguments smaller than a stack slot are padded downward.  */
   3455  1.1  mrg   if (mode != BLKmode)
   3456  1.1  mrg     return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
   3457  1.1  mrg 	    ? PAD_UPWARD : PAD_DOWNWARD);
   3458  1.1  mrg 
   3459  1.1  mrg   return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
   3460  1.1  mrg 	  ? PAD_UPWARD : PAD_DOWNWARD);
   3461  1.1  mrg }
   3462  1.1  mrg 
   3463  1.1  mrg pad_direction
   3464  1.1  mrg nios2_block_reg_padding (machine_mode mode, tree type,
   3465  1.1  mrg                          int first ATTRIBUTE_UNUSED)
   3466  1.1  mrg {
   3467  1.1  mrg   return nios2_function_arg_padding (mode, type);
   3468  1.1  mrg }
   3469  1.1  mrg 
   3470  1.1  mrg /* Emit RTL insns to initialize the variable parts of a trampoline.
   3471  1.1  mrg    FNADDR is an RTX for the address of the function's pure code.
   3472  1.1  mrg    CXT is an RTX for the static chain value for the function.
   3473  1.1  mrg    On Nios II, we handle this by a library call.  */
   3474  1.1  mrg static void
   3475  1.1  mrg nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
   3476  1.1  mrg {
   3477  1.1  mrg   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
   3478  1.1  mrg   rtx ctx_reg = force_reg (Pmode, cxt);
   3479  1.1  mrg   rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
   3480  1.1  mrg 
   3481  1.1  mrg   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
   3482  1.1  mrg 		     LCT_NORMAL, VOIDmode, addr, Pmode, fnaddr, Pmode,
   3483  1.1  mrg 		     ctx_reg, Pmode);
   3484  1.1  mrg }
   3485  1.1  mrg 
   3486  1.1  mrg /* Implement TARGET_FUNCTION_VALUE.  */
   3487  1.1  mrg static rtx
   3488  1.1  mrg nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
   3489  1.1  mrg 		      bool outgoing ATTRIBUTE_UNUSED)
   3490  1.1  mrg {
   3491  1.1  mrg   return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
   3492  1.1  mrg }
   3493  1.1  mrg 
   3494  1.1  mrg /* Implement TARGET_LIBCALL_VALUE.  */
   3495  1.1  mrg static rtx
   3496  1.1  mrg nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
   3497  1.1  mrg {
   3498  1.1  mrg   return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
   3499  1.1  mrg }
   3500  1.1  mrg 
   3501  1.1  mrg /* Implement TARGET_FUNCTION_VALUE_REGNO_P.  */
   3502  1.1  mrg static bool
   3503  1.1  mrg nios2_function_value_regno_p (const unsigned int regno)
   3504  1.1  mrg {
   3505  1.1  mrg   return regno == FIRST_RETVAL_REGNO;
   3506  1.1  mrg }
   3507  1.1  mrg 
   3508  1.1  mrg /* Implement TARGET_RETURN_IN_MEMORY.  */
   3509  1.1  mrg static bool
   3510  1.1  mrg nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
   3511  1.1  mrg {
   3512  1.1  mrg   return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
   3513  1.1  mrg 	  || int_size_in_bytes (type) == -1);
   3514  1.1  mrg }
   3515  1.1  mrg 
   3516  1.1  mrg /* TODO: It may be possible to eliminate the copyback and implement
   3517  1.1  mrg    own va_arg type.  */
   3518  1.1  mrg static void
   3519  1.1  mrg nios2_setup_incoming_varargs (cumulative_args_t cum_v,
   3520  1.1  mrg 			      const function_arg_info &arg,
   3521  1.1  mrg 			      int *pretend_size, int second_time)
   3522  1.1  mrg {
   3523  1.1  mrg   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   3524  1.1  mrg   CUMULATIVE_ARGS local_cum;
   3525  1.1  mrg   cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
   3526  1.1  mrg   int regs_to_push;
   3527  1.1  mrg   int pret_size;
   3528  1.1  mrg 
   3529  1.1  mrg   cfun->machine->uses_anonymous_args = 1;
   3530  1.1  mrg   local_cum = *cum;
   3531  1.1  mrg   nios2_function_arg_advance (local_cum_v, arg);
   3532  1.1  mrg 
   3533  1.1  mrg   regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
   3534  1.1  mrg 
   3535  1.1  mrg   /* If we can use CDX stwm to push the arguments on the stack,
   3536  1.1  mrg      nios2_expand_prologue will do that instead.  */
   3537  1.1  mrg   if (!TARGET_HAS_CDX && !second_time && regs_to_push > 0)
   3538  1.1  mrg     {
   3539  1.1  mrg       rtx ptr = virtual_incoming_args_rtx;
   3540  1.1  mrg       rtx mem = gen_rtx_MEM (BLKmode, ptr);
   3541  1.1  mrg       emit_insn (gen_blockage ());
   3542  1.1  mrg       move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
   3543  1.1  mrg 			   regs_to_push);
   3544  1.1  mrg       emit_insn (gen_blockage ());
   3545  1.1  mrg     }
   3546  1.1  mrg 
   3547  1.1  mrg   pret_size = regs_to_push * UNITS_PER_WORD;
   3548  1.1  mrg   if (pret_size)
   3549  1.1  mrg     *pretend_size = pret_size;
   3550  1.1  mrg }
   3551  1.1  mrg 
   3552  1.1  mrg 
   3553  1.1  mrg 
   3555  1.1  mrg /* Init FPU builtins.  */
   3556  1.1  mrg static void
   3557  1.1  mrg nios2_init_fpu_builtins (int start_code)
   3558  1.1  mrg {
   3559  1.1  mrg   tree fndecl;
   3560  1.1  mrg   char builtin_name[64] = "__builtin_custom_";
   3561  1.1  mrg   unsigned int i, n = strlen ("__builtin_custom_");
   3562  1.1  mrg 
   3563  1.1  mrg   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   3564  1.1  mrg     {
   3565  1.1  mrg       snprintf (builtin_name + n, sizeof (builtin_name) - n,
   3566  1.1  mrg 		"%s", N2FPU_NAME (i));
   3567  1.1  mrg       fndecl =
   3568  1.1  mrg 	add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
   3569  1.1  mrg 			      start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
   3570  1.1  mrg       nios2_register_builtin_fndecl (start_code + i, fndecl);
   3571  1.1  mrg     }
   3572  1.1  mrg }
   3573  1.1  mrg 
   3574  1.1  mrg /* Helper function for expanding FPU builtins.  */
   3575  1.1  mrg static rtx
   3576  1.1  mrg nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
   3577  1.1  mrg {
   3578  1.1  mrg   struct expand_operand ops[MAX_RECOG_OPERANDS];
   3579  1.1  mrg   enum insn_code icode = N2FPU_ICODE (code);
   3580  1.1  mrg   int nargs, argno, opno = 0;
   3581  1.1  mrg   int num_operands = N2FPU (code).num_operands;
   3582  1.1  mrg   machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
   3583  1.1  mrg   bool has_target_p = (dst_mode != VOIDmode);
   3584  1.1  mrg 
   3585  1.1  mrg   if (N2FPU_N (code) < 0)
   3586  1.1  mrg     fatal_error (input_location,
   3587  1.1  mrg 		 "cannot call %<__builtin_custom_%s%> without specifying "
   3588  1.1  mrg 		 "switch %<-mcustom-%s%>",
   3589  1.1  mrg 		 N2FPU_NAME (code), N2FPU_NAME (code));
   3590  1.1  mrg   if (has_target_p)
   3591  1.1  mrg     create_output_operand (&ops[opno++], target, dst_mode);
   3592  1.1  mrg   else
   3593  1.1  mrg     /* Subtract away the count of the VOID return, mainly for fwrx/fwry.   */
   3594  1.1  mrg     num_operands -= 1;
   3595  1.1  mrg   nargs = call_expr_nargs (exp);
   3596  1.1  mrg   for (argno = 0; argno < nargs; argno++)
   3597  1.1  mrg     {
   3598  1.1  mrg       tree arg = CALL_EXPR_ARG (exp, argno);
   3599  1.1  mrg       create_input_operand (&ops[opno++], expand_normal (arg),
   3600  1.1  mrg 			    TYPE_MODE (TREE_TYPE (arg)));
   3601  1.1  mrg     }
   3602  1.1  mrg   if (!maybe_expand_insn (icode, num_operands, ops))
   3603  1.1  mrg     {
   3604  1.1  mrg       error ("invalid argument to built-in function");
   3605  1.1  mrg       return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
   3606  1.1  mrg     }
   3607  1.1  mrg   return has_target_p ? ops[0].value : const0_rtx;
   3608  1.1  mrg }
   3609  1.1  mrg 
   3610  1.1  mrg /* Nios II has custom instruction built-in functions of the forms:
   3611  1.1  mrg    __builtin_custom_n
   3612  1.1  mrg    __builtin_custom_nX
   3613  1.1  mrg    __builtin_custom_nXX
   3614  1.1  mrg    __builtin_custom_Xn
   3615  1.1  mrg    __builtin_custom_XnX
   3616  1.1  mrg    __builtin_custom_XnXX
   3617  1.1  mrg 
   3618  1.1  mrg    where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
   3619  1.1  mrg    Therefore with 0-1 return values, and 0-2 arguments, we have a
   3620  1.1  mrg    total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
   3621  1.1  mrg */
   3622  1.1  mrg #define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
   3623  1.1  mrg static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
   3624  1.1  mrg 
   3625  1.1  mrg static void
   3626  1.1  mrg nios2_init_custom_builtins (int start_code)
   3627  1.1  mrg {
   3628  1.1  mrg   tree builtin_ftype, ret_type, fndecl;
   3629  1.1  mrg   char builtin_name[32] = "__builtin_custom_";
   3630  1.1  mrg   int n = strlen ("__builtin_custom_");
   3631  1.1  mrg   int builtin_code = 0;
   3632  1.1  mrg   int lhs, rhs1, rhs2;
   3633  1.1  mrg 
   3634  1.1  mrg   struct { tree type; const char *c; } op[4];
   3635  1.1  mrg   /* z */ op[0].c = "";  op[0].type = NULL_TREE;
   3636  1.1  mrg   /* f */ op[1].c = "f"; op[1].type = float_type_node;
   3637  1.1  mrg   /* i */ op[2].c = "i"; op[2].type = integer_type_node;
   3638  1.1  mrg   /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
   3639  1.1  mrg 
   3640  1.1  mrg   /* We enumerate through the possible operand types to create all the
   3641  1.1  mrg      __builtin_custom_XnXX function tree types.  Note that these may slightly
   3642  1.1  mrg      overlap with the function types created for other fixed builtins.  */
   3643  1.1  mrg 
   3644  1.1  mrg   for (lhs = 0; lhs < 4; lhs++)
   3645  1.1  mrg     for (rhs1 = 0; rhs1 < 4; rhs1++)
   3646  1.1  mrg       for (rhs2 = 0; rhs2 < 4; rhs2++)
   3647  1.1  mrg 	{
   3648  1.1  mrg 	  if (rhs1 == 0 && rhs2 != 0)
   3649  1.1  mrg 	    continue;
   3650  1.1  mrg 	  ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
   3651  1.1  mrg 	  builtin_ftype
   3652  1.1  mrg 	    = build_function_type_list (ret_type, integer_type_node,
   3653  1.1  mrg 					op[rhs1].type, op[rhs2].type,
   3654  1.1  mrg 					NULL_TREE);
   3655  1.1  mrg 	  /* Save copy of parameter string into custom_builtin_name[].  */
   3656  1.1  mrg 	  snprintf (custom_builtin_name[builtin_code], 5, "%sn%s%s",
   3657  1.1  mrg 		    op[lhs].c, op[rhs1].c, op[rhs2].c);
   3658  1.1  mrg 	  strncpy (builtin_name + n, custom_builtin_name[builtin_code], 5);
   3659  1.1  mrg 	  fndecl =
   3660  1.1  mrg 	    add_builtin_function (builtin_name, builtin_ftype,
   3661  1.1  mrg 				  start_code + builtin_code,
   3662  1.1  mrg 				  BUILT_IN_MD, NULL, NULL_TREE);
   3663  1.1  mrg 	  nios2_register_builtin_fndecl (start_code + builtin_code, fndecl);
   3664  1.1  mrg 	  builtin_code += 1;
   3665  1.1  mrg 	}
   3666  1.1  mrg }
   3667  1.1  mrg 
   3668  1.1  mrg /* Helper function for expanding custom builtins.  */
   3669  1.1  mrg static rtx
   3670  1.1  mrg nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
   3671  1.1  mrg {
   3672  1.1  mrg   bool has_target_p = (TREE_TYPE (exp) != void_type_node);
   3673  1.1  mrg   machine_mode tmode = VOIDmode;
   3674  1.1  mrg   int nargs, argno;
   3675  1.1  mrg   rtx value, insn, unspec_args[3];
   3676  1.1  mrg   tree arg;
   3677  1.1  mrg 
   3678  1.1  mrg   /* XnXX form.  */
   3679  1.1  mrg   if (has_target_p)
   3680  1.1  mrg     {
   3681  1.1  mrg       tmode = TYPE_MODE (TREE_TYPE (exp));
   3682  1.1  mrg       if (!target || GET_MODE (target) != tmode
   3683  1.1  mrg 	  || !REG_P (target))
   3684  1.1  mrg 	target = gen_reg_rtx (tmode);
   3685  1.1  mrg     }
   3686  1.1  mrg 
   3687  1.1  mrg   nargs = call_expr_nargs (exp);
   3688  1.1  mrg   for (argno = 0; argno < nargs; argno++)
   3689  1.1  mrg     {
   3690  1.1  mrg       arg = CALL_EXPR_ARG (exp, argno);
   3691  1.1  mrg       value = expand_normal (arg);
   3692  1.1  mrg       unspec_args[argno] = value;
   3693  1.1  mrg       if (argno == 0)
   3694  1.1  mrg 	{
   3695  1.1  mrg 	  if (!custom_insn_opcode (value, VOIDmode))
   3696  1.1  mrg 	    error ("custom instruction opcode must be a compile-time "
   3697  1.1  mrg 		   "constant in the range 0-255 for %<__builtin_custom_%s%>",
   3698  1.1  mrg 		   custom_builtin_name[index]);
   3699  1.1  mrg 	}
   3700  1.1  mrg       else
   3701  1.1  mrg 	/* For other arguments, force into a register.  */
   3702  1.1  mrg 	unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
   3703  1.1  mrg 					unspec_args[argno]);
   3704  1.1  mrg     }
   3705  1.1  mrg   /* Fill remaining unspec operands with zero.  */
   3706  1.1  mrg   for (; argno < 3; argno++)
   3707  1.1  mrg     unspec_args[argno] = const0_rtx;
   3708  1.1  mrg 
   3709  1.1  mrg   insn = (has_target_p
   3710  1.1  mrg 	  ? gen_rtx_SET (target,
   3711  1.1  mrg 			 gen_rtx_UNSPEC_VOLATILE (tmode,
   3712  1.1  mrg 						  gen_rtvec_v (3, unspec_args),
   3713  1.1  mrg 						  UNSPECV_CUSTOM_XNXX))
   3714  1.1  mrg 	  : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
   3715  1.1  mrg 				     UNSPECV_CUSTOM_NXX));
   3716  1.1  mrg   emit_insn (insn);
   3717  1.1  mrg   return has_target_p ? target : const0_rtx;
   3718  1.1  mrg }
   3719  1.1  mrg 
   3720  1.1  mrg 
   3721  1.1  mrg 
   3722  1.1  mrg 
   3724  1.1  mrg /* Main definition of built-in functions.  Nios II has a small number of fixed
   3725  1.1  mrg    builtins, plus a large number of FPU insn builtins, and builtins for
   3726  1.1  mrg    generating custom instructions.  */
   3727  1.1  mrg 
   3728  1.1  mrg struct nios2_builtin_desc
   3729  1.1  mrg {
   3730  1.1  mrg   enum insn_code icode;
   3731  1.1  mrg   enum nios2_arch_type arch;
   3732  1.1  mrg   enum nios2_ftcode ftype;
   3733  1.1  mrg   const char *name;
   3734  1.1  mrg };
   3735  1.1  mrg 
   3736  1.1  mrg #define N2_BUILTINS					\
   3737  1.1  mrg   N2_BUILTIN_DEF (sync,    R1, N2_FTYPE_VOID_VOID)	\
   3738  1.1  mrg   N2_BUILTIN_DEF (ldbio,   R1, N2_FTYPE_SI_CVPTR)	\
   3739  1.1  mrg   N2_BUILTIN_DEF (ldbuio,  R1, N2_FTYPE_UI_CVPTR)	\
   3740  1.1  mrg   N2_BUILTIN_DEF (ldhio,   R1, N2_FTYPE_SI_CVPTR)	\
   3741  1.1  mrg   N2_BUILTIN_DEF (ldhuio,  R1, N2_FTYPE_UI_CVPTR)	\
   3742  1.1  mrg   N2_BUILTIN_DEF (ldwio,   R1, N2_FTYPE_SI_CVPTR)	\
   3743  1.1  mrg   N2_BUILTIN_DEF (stbio,   R1, N2_FTYPE_VOID_VPTR_SI)	\
   3744  1.1  mrg   N2_BUILTIN_DEF (sthio,   R1, N2_FTYPE_VOID_VPTR_SI)	\
   3745  1.1  mrg   N2_BUILTIN_DEF (stwio,   R1, N2_FTYPE_VOID_VPTR_SI)	\
   3746  1.1  mrg   N2_BUILTIN_DEF (rdctl,   R1, N2_FTYPE_SI_SI)		\
   3747  1.1  mrg   N2_BUILTIN_DEF (wrctl,   R1, N2_FTYPE_VOID_SI_SI)	\
   3748  1.1  mrg   N2_BUILTIN_DEF (rdprs,   R1, N2_FTYPE_SI_SI_SI)	\
   3749  1.1  mrg   N2_BUILTIN_DEF (flushd,  R1, N2_FTYPE_VOID_VPTR)	\
   3750  1.1  mrg   N2_BUILTIN_DEF (flushda, R1, N2_FTYPE_VOID_VPTR)	\
   3751  1.1  mrg   N2_BUILTIN_DEF (wrpie,   R2, N2_FTYPE_SI_SI)		\
   3752  1.1  mrg   N2_BUILTIN_DEF (eni,     R2, N2_FTYPE_VOID_SI)	\
   3753  1.1  mrg   N2_BUILTIN_DEF (ldex,    R2, N2_FTYPE_SI_CVPTR)	\
   3754  1.1  mrg   N2_BUILTIN_DEF (ldsex,   R2, N2_FTYPE_SI_CVPTR)	\
   3755  1.1  mrg   N2_BUILTIN_DEF (stex,    R2, N2_FTYPE_SI_VPTR_SI)	\
   3756  1.1  mrg   N2_BUILTIN_DEF (stsex,   R2, N2_FTYPE_SI_VPTR_SI)
   3757  1.1  mrg 
   3758  1.1  mrg enum nios2_builtin_code {
   3759  1.1  mrg #define N2_BUILTIN_DEF(name, arch, ftype) NIOS2_BUILTIN_ ## name,
   3760  1.1  mrg   N2_BUILTINS
   3761  1.1  mrg #undef N2_BUILTIN_DEF
   3762  1.1  mrg   NUM_FIXED_NIOS2_BUILTINS
   3763  1.1  mrg };
   3764  1.1  mrg 
   3765  1.1  mrg static const struct nios2_builtin_desc nios2_builtins[] = {
   3766  1.1  mrg #define N2_BUILTIN_DEF(name, arch, ftype)		\
   3767  1.1  mrg   { CODE_FOR_ ## name, ARCH_ ## arch, ftype, "__builtin_" #name },
   3768  1.1  mrg   N2_BUILTINS
   3769  1.1  mrg #undef N2_BUILTIN_DEF
   3770  1.1  mrg };
   3771  1.1  mrg 
   3772  1.1  mrg /* Start/ends of FPU/custom insn builtin index ranges.  */
   3773  1.1  mrg static unsigned int nios2_fpu_builtin_base;
   3774  1.1  mrg static unsigned int nios2_custom_builtin_base;
   3775  1.1  mrg static unsigned int nios2_custom_builtin_end;
   3776  1.1  mrg 
   3777  1.1  mrg /* Implement TARGET_INIT_BUILTINS.  */
   3778  1.1  mrg static void
   3779  1.1  mrg nios2_init_builtins (void)
   3780  1.1  mrg {
   3781  1.1  mrg   unsigned int i;
   3782  1.1  mrg 
   3783  1.1  mrg   /* Initialize fixed builtins.  */
   3784  1.1  mrg   for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
   3785  1.1  mrg     {
   3786  1.1  mrg       const struct nios2_builtin_desc *d = &nios2_builtins[i];
   3787  1.1  mrg       tree fndecl =
   3788  1.1  mrg 	add_builtin_function (d->name, nios2_ftype (d->ftype), i,
   3789  1.1  mrg 			      BUILT_IN_MD, NULL, NULL);
   3790  1.1  mrg       nios2_register_builtin_fndecl (i, fndecl);
   3791  1.1  mrg     }
   3792  1.1  mrg 
   3793  1.1  mrg   /* Initialize FPU builtins.  */
   3794  1.1  mrg   nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
   3795  1.1  mrg   nios2_init_fpu_builtins (nios2_fpu_builtin_base);
   3796  1.1  mrg 
   3797  1.1  mrg   /* Initialize custom insn builtins.  */
   3798  1.1  mrg   nios2_custom_builtin_base
   3799  1.1  mrg     = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
   3800  1.1  mrg   nios2_custom_builtin_end
   3801  1.1  mrg     = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
   3802  1.1  mrg   nios2_init_custom_builtins (nios2_custom_builtin_base);
   3803  1.1  mrg }
   3804  1.1  mrg 
   3805  1.1  mrg /* Array of fndecls for TARGET_BUILTIN_DECL.  */
   3806  1.1  mrg #define NIOS2_NUM_BUILTINS \
   3807  1.1  mrg   (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS)
   3808  1.1  mrg static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS];
   3809  1.1  mrg 
   3810  1.1  mrg static void
   3811  1.1  mrg nios2_register_builtin_fndecl (unsigned code, tree fndecl)
   3812  1.1  mrg {
   3813  1.1  mrg   nios2_builtin_decls[code] = fndecl;
   3814  1.1  mrg }
   3815  1.1  mrg 
   3816  1.1  mrg /* Implement TARGET_BUILTIN_DECL.  */
   3817  1.1  mrg static tree
   3818  1.1  mrg nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
   3819  1.1  mrg {
   3820  1.1  mrg   gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls));
   3821  1.1  mrg 
   3822  1.1  mrg   if (code >= nios2_custom_builtin_end)
   3823  1.1  mrg     return error_mark_node;
   3824  1.1  mrg 
   3825  1.1  mrg   if (code >= nios2_fpu_builtin_base
   3826  1.1  mrg       && code < nios2_custom_builtin_base
   3827  1.1  mrg       && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base))
   3828  1.1  mrg     return error_mark_node;
   3829  1.1  mrg 
   3830  1.1  mrg   return nios2_builtin_decls[code];
   3831  1.1  mrg }
   3832  1.1  mrg 
   3833  1.1  mrg 
   3834  1.1  mrg /* Low-level built-in expand routine.  */
   3836  1.1  mrg static rtx
   3837  1.1  mrg nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
   3838  1.1  mrg 			   struct expand_operand *ops, bool has_target_p)
   3839  1.1  mrg {
   3840  1.1  mrg   if (maybe_expand_insn (d->icode, n, ops))
   3841  1.1  mrg     return has_target_p ? ops[0].value : const0_rtx;
   3842  1.1  mrg   else
   3843  1.1  mrg     {
   3844  1.1  mrg       error ("invalid argument to built-in function %s", d->name);
   3845  1.1  mrg       return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
   3846  1.1  mrg     }
   3847  1.1  mrg }
   3848  1.1  mrg 
   3849  1.1  mrg /* Expand ldio/stio and ldex/ldsex/stex/stsex form load-store
   3850  1.1  mrg    instruction builtins.  */
   3851  1.1  mrg static rtx
   3852  1.1  mrg nios2_expand_ldst_builtin (tree exp, rtx target,
   3853  1.1  mrg 			   const struct nios2_builtin_desc *d)
   3854  1.1  mrg {
   3855  1.1  mrg   bool has_target_p;
   3856  1.1  mrg   rtx addr, mem, val;
   3857  1.1  mrg   struct expand_operand ops[MAX_RECOG_OPERANDS];
   3858  1.1  mrg   machine_mode mode = insn_data[d->icode].operand[0].mode;
   3859  1.1  mrg 
   3860  1.1  mrg   addr = expand_normal (CALL_EXPR_ARG (exp, 0));
   3861  1.1  mrg   mem = gen_rtx_MEM (mode, addr);
   3862  1.1  mrg 
   3863  1.1  mrg   if (insn_data[d->icode].operand[0].allows_mem)
   3864  1.1  mrg     {
   3865  1.1  mrg       /* stxio/stex/stsex.  */
   3866  1.1  mrg       val = expand_normal (CALL_EXPR_ARG (exp, 1));
   3867  1.1  mrg       if (CONST_INT_P (val))
   3868  1.1  mrg 	val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
   3869  1.1  mrg       val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
   3870  1.1  mrg       create_output_operand (&ops[0], mem, mode);
   3871  1.1  mrg       create_input_operand (&ops[1], val, mode);
   3872  1.1  mrg       if (insn_data[d->icode].n_operands == 3)
   3873  1.1  mrg 	{
   3874  1.1  mrg 	  /* stex/stsex status value, returned as result of function.  */
   3875  1.1  mrg 	  create_output_operand (&ops[2], target, mode);
   3876  1.1  mrg 	  has_target_p = true;
   3877  1.1  mrg 	}
   3878  1.1  mrg       else
   3879  1.1  mrg 	has_target_p = false;
   3880  1.1  mrg     }
   3881  1.1  mrg   else
   3882  1.1  mrg     {
   3883  1.1  mrg       /* ldxio.  */
   3884  1.1  mrg       create_output_operand (&ops[0], target, mode);
   3885  1.1  mrg       create_input_operand (&ops[1], mem, mode);
   3886  1.1  mrg       has_target_p = true;
   3887  1.1  mrg     }
   3888  1.1  mrg   return nios2_expand_builtin_insn (d, insn_data[d->icode].n_operands, ops,
   3889  1.1  mrg 				    has_target_p);
   3890  1.1  mrg }
   3891  1.1  mrg 
   3892  1.1  mrg /* Expand rdctl/wrctl builtins.  */
   3893  1.1  mrg static rtx
   3894  1.1  mrg nios2_expand_rdwrctl_builtin (tree exp, rtx target,
   3895  1.1  mrg 			     const struct nios2_builtin_desc *d)
   3896  1.1  mrg {
   3897  1.1  mrg   bool has_target_p = (insn_data[d->icode].operand[0].predicate
   3898  1.1  mrg 		       == register_operand);
   3899  1.1  mrg   rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
   3900  1.1  mrg   struct expand_operand ops[MAX_RECOG_OPERANDS];
   3901  1.1  mrg   if (!rdwrctl_operand (ctlcode, VOIDmode))
   3902  1.1  mrg     {
   3903  1.1  mrg       error ("control register number must be in range 0-31 for %s",
   3904  1.1  mrg 	     d->name);
   3905  1.1  mrg       return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
   3906  1.1  mrg     }
   3907  1.1  mrg   if (has_target_p)
   3908  1.1  mrg     {
   3909  1.1  mrg       create_output_operand (&ops[0], target, SImode);
   3910  1.1  mrg       create_integer_operand (&ops[1], INTVAL (ctlcode));
   3911  1.1  mrg     }
   3912  1.1  mrg   else
   3913  1.1  mrg     {
   3914  1.1  mrg       rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
   3915  1.1  mrg       create_integer_operand (&ops[0], INTVAL (ctlcode));
   3916  1.1  mrg       create_input_operand (&ops[1], val, SImode);
   3917  1.1  mrg     }
   3918  1.1  mrg   return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
   3919  1.1  mrg }
   3920  1.1  mrg 
   3921  1.1  mrg static rtx
   3922  1.1  mrg nios2_expand_rdprs_builtin (tree exp, rtx target,
   3923  1.1  mrg 			    const struct nios2_builtin_desc *d)
   3924  1.1  mrg {
   3925  1.1  mrg   rtx reg = expand_normal (CALL_EXPR_ARG (exp, 0));
   3926  1.1  mrg   rtx imm = expand_normal (CALL_EXPR_ARG (exp, 1));
   3927  1.1  mrg   struct expand_operand ops[MAX_RECOG_OPERANDS];
   3928  1.1  mrg 
   3929  1.1  mrg   if (!rdwrctl_operand (reg, VOIDmode))
   3930  1.1  mrg     {
   3931  1.1  mrg       error ("register number must be in range 0-31 for %s",
   3932  1.1  mrg 	     d->name);
   3933  1.1  mrg       return gen_reg_rtx (SImode);
   3934  1.1  mrg     }
   3935  1.1  mrg 
   3936  1.1  mrg   if (!rdprs_dcache_operand (imm, VOIDmode))
   3937  1.1  mrg     {
   3938  1.1  mrg       error ("immediate value must fit into a %d-bit integer for %s",
   3939  1.1  mrg 	     (TARGET_ARCH_R2) ? 12 : 16, d->name);
   3940  1.1  mrg       return gen_reg_rtx (SImode);
   3941  1.1  mrg     }
   3942  1.1  mrg 
   3943  1.1  mrg   create_output_operand (&ops[0], target, SImode);
   3944  1.1  mrg   create_input_operand (&ops[1], reg, SImode);
   3945  1.1  mrg   create_integer_operand (&ops[2], INTVAL (imm));
   3946  1.1  mrg 
   3947  1.1  mrg   return nios2_expand_builtin_insn (d, 3, ops, true);
   3948  1.1  mrg }
   3949  1.1  mrg 
   3950  1.1  mrg static rtx
   3951  1.1  mrg nios2_expand_cache_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
   3952  1.1  mrg 			    const struct nios2_builtin_desc *d)
   3953  1.1  mrg {
   3954  1.1  mrg   rtx mem, addr;
   3955  1.1  mrg   struct expand_operand ops[MAX_RECOG_OPERANDS];
   3956  1.1  mrg 
   3957  1.1  mrg   addr = expand_normal (CALL_EXPR_ARG (exp, 0));
   3958  1.1  mrg   mem = gen_rtx_MEM (SImode, addr);
   3959  1.1  mrg 
   3960  1.1  mrg   create_input_operand (&ops[0], mem, SImode);
   3961  1.1  mrg 
   3962  1.1  mrg   return nios2_expand_builtin_insn (d, 1, ops, false);
   3963  1.1  mrg }
   3964  1.1  mrg 
   3965  1.1  mrg static rtx
   3966  1.1  mrg nios2_expand_wrpie_builtin (tree exp, rtx target,
   3967  1.1  mrg 			    const struct nios2_builtin_desc *d)
   3968  1.1  mrg {
   3969  1.1  mrg   rtx val;
   3970  1.1  mrg   struct expand_operand ops[MAX_RECOG_OPERANDS];
   3971  1.1  mrg 
   3972  1.1  mrg   val = expand_normal (CALL_EXPR_ARG (exp, 0));
   3973  1.1  mrg   create_input_operand (&ops[1], val, SImode);
   3974  1.1  mrg   create_output_operand (&ops[0], target, SImode);
   3975  1.1  mrg 
   3976  1.1  mrg   return nios2_expand_builtin_insn (d, 2, ops, true);
   3977  1.1  mrg }
   3978  1.1  mrg 
   3979  1.1  mrg static rtx
   3980  1.1  mrg nios2_expand_eni_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
   3981  1.1  mrg 			    const struct nios2_builtin_desc *d)
   3982  1.1  mrg {
   3983  1.1  mrg   rtx imm = expand_normal (CALL_EXPR_ARG (exp, 0));
   3984  1.1  mrg   struct expand_operand ops[MAX_RECOG_OPERANDS];
   3985  1.1  mrg 
   3986  1.1  mrg   if (INTVAL (imm) != 0 && INTVAL (imm) != 1)
   3987  1.1  mrg     {
   3988  1.1  mrg       error ("the ENI instruction operand must be either 0 or 1");
   3989  1.1  mrg       return const0_rtx;
   3990  1.1  mrg     }
   3991  1.1  mrg   create_integer_operand (&ops[0], INTVAL (imm));
   3992  1.1  mrg 
   3993  1.1  mrg   return nios2_expand_builtin_insn (d, 1, ops, false);
   3994  1.1  mrg }
   3995  1.1  mrg 
   3996  1.1  mrg /* Implement TARGET_EXPAND_BUILTIN.  Expand an expression EXP that calls
   3997  1.1  mrg    a built-in function, with result going to TARGET if that's convenient
   3998  1.1  mrg    (and in mode MODE if that's convenient).
   3999  1.1  mrg    SUBTARGET may be used as the target for computing one of EXP's operands.
   4000  1.1  mrg    IGNORE is nonzero if the value is to be ignored.  */
   4001  1.1  mrg 
   4002  1.1  mrg static rtx
   4003  1.1  mrg nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
   4004  1.1  mrg                       machine_mode mode ATTRIBUTE_UNUSED,
   4005  1.1  mrg 		      int ignore ATTRIBUTE_UNUSED)
   4006  1.1  mrg {
   4007  1.1  mrg   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   4008  1.1  mrg   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   4009  1.1  mrg 
   4010  1.1  mrg   if (fcode < nios2_fpu_builtin_base)
   4011  1.1  mrg     {
   4012  1.1  mrg       const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
   4013  1.1  mrg 
   4014  1.1  mrg       if (d->arch > nios2_arch_option)
   4015  1.1  mrg 	{
   4016  1.1  mrg 	  error ("built-in function %s requires Nios II R%d",
   4017  1.1  mrg 		 d->name, (int) d->arch);
   4018  1.1  mrg 	  /* Given it is invalid, just generate a normal call.  */
   4019  1.1  mrg 	  return expand_call (exp, target, ignore);
   4020  1.1  mrg 	}
   4021  1.1  mrg 
   4022  1.1  mrg       switch (fcode)
   4023  1.1  mrg 	{
   4024  1.1  mrg 	case NIOS2_BUILTIN_sync:
   4025  1.1  mrg 	  emit_insn (gen_sync ());
   4026  1.1  mrg 	  return const0_rtx;
   4027  1.1  mrg 
   4028  1.1  mrg 	case NIOS2_BUILTIN_ldbio:
   4029  1.1  mrg 	case NIOS2_BUILTIN_ldbuio:
   4030  1.1  mrg 	case NIOS2_BUILTIN_ldhio:
   4031  1.1  mrg 	case NIOS2_BUILTIN_ldhuio:
   4032  1.1  mrg 	case NIOS2_BUILTIN_ldwio:
   4033  1.1  mrg 	case NIOS2_BUILTIN_stbio:
   4034  1.1  mrg 	case NIOS2_BUILTIN_sthio:
   4035  1.1  mrg 	case NIOS2_BUILTIN_stwio:
   4036  1.1  mrg 	case NIOS2_BUILTIN_ldex:
   4037  1.1  mrg 	case NIOS2_BUILTIN_ldsex:
   4038  1.1  mrg 	case NIOS2_BUILTIN_stex:
   4039  1.1  mrg 	case NIOS2_BUILTIN_stsex:
   4040  1.1  mrg 	  return nios2_expand_ldst_builtin (exp, target, d);
   4041  1.1  mrg 
   4042  1.1  mrg 	case NIOS2_BUILTIN_rdctl:
   4043  1.1  mrg 	case NIOS2_BUILTIN_wrctl:
   4044  1.1  mrg 	  return nios2_expand_rdwrctl_builtin (exp, target, d);
   4045  1.1  mrg 
   4046  1.1  mrg 	case NIOS2_BUILTIN_rdprs:
   4047  1.1  mrg 	  return nios2_expand_rdprs_builtin (exp, target, d);
   4048  1.1  mrg 
   4049  1.1  mrg 	case NIOS2_BUILTIN_flushd:
   4050  1.1  mrg 	case NIOS2_BUILTIN_flushda:
   4051  1.1  mrg 	  return nios2_expand_cache_builtin (exp, target, d);
   4052  1.1  mrg 
   4053  1.1  mrg 	case NIOS2_BUILTIN_wrpie:
   4054  1.1  mrg 	  return nios2_expand_wrpie_builtin (exp, target, d);
   4055  1.1  mrg 
   4056  1.1  mrg 	case NIOS2_BUILTIN_eni:
   4057  1.1  mrg 	  return nios2_expand_eni_builtin (exp, target, d);
   4058  1.1  mrg 
   4059  1.1  mrg 	default:
   4060  1.1  mrg 	  gcc_unreachable ();
   4061  1.1  mrg 	}
   4062  1.1  mrg     }
   4063  1.1  mrg   else if (fcode < nios2_custom_builtin_base)
   4064  1.1  mrg     /* FPU builtin range.  */
   4065  1.1  mrg     return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
   4066  1.1  mrg 				     target);
   4067  1.1  mrg   else if (fcode < nios2_custom_builtin_end)
   4068  1.1  mrg     /* Custom insn builtin range.  */
   4069  1.1  mrg     return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
   4070  1.1  mrg 					target);
   4071  1.1  mrg   else
   4072  1.1  mrg     gcc_unreachable ();
   4073  1.1  mrg }
   4074  1.1  mrg 
   4075  1.1  mrg /* Implement TARGET_INIT_LIBFUNCS.  */
   4076  1.1  mrg static void ATTRIBUTE_UNUSED
   4077  1.1  mrg nios2_init_libfuncs (void)
   4078  1.1  mrg {
   4079  1.1  mrg   init_sync_libfuncs (UNITS_PER_WORD);
   4080  1.1  mrg }
   4081  1.1  mrg 
   4082  1.1  mrg 
   4083  1.1  mrg 
   4085  1.1  mrg /* Register a custom code use, and signal error if a conflict was found.  */
   4086  1.1  mrg static void
   4087  1.1  mrg nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
   4088  1.1  mrg 			    int index)
   4089  1.1  mrg {
   4090  1.1  mrg   gcc_assert (N <= 255);
   4091  1.1  mrg 
   4092  1.1  mrg   if (status == CCS_FPU)
   4093  1.1  mrg     {
   4094  1.1  mrg       if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
   4095  1.1  mrg 	{
   4096  1.1  mrg 	  custom_code_conflict = true;
   4097  1.1  mrg 	  error ("switch %<-mcustom-%s%> conflicts with "
   4098  1.1  mrg 		 "switch %<-mcustom-%s%>",
   4099  1.1  mrg 		 N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
   4100  1.1  mrg 	}
   4101  1.1  mrg       else if (custom_code_status[N] == CCS_BUILTIN_CALL)
   4102  1.1  mrg 	{
   4103  1.1  mrg 	  custom_code_conflict = true;
   4104  1.1  mrg 	  error ("call to %<__builtin_custom_%s%> conflicts with "
   4105  1.1  mrg 		 "switch %<-mcustom-%s%>",
   4106  1.1  mrg 		 custom_builtin_name[custom_code_index[N]],
   4107  1.1  mrg 		 N2FPU_NAME (index));
   4108  1.1  mrg 	}
   4109  1.1  mrg     }
   4110  1.1  mrg   else if (status == CCS_BUILTIN_CALL)
   4111  1.1  mrg     {
   4112  1.1  mrg       if (custom_code_status[N] == CCS_FPU)
   4113  1.1  mrg 	{
   4114  1.1  mrg 	  custom_code_conflict = true;
   4115  1.1  mrg 	  error ("call to %<__builtin_custom_%s%> conflicts with "
   4116  1.1  mrg 		 "switch %<-mcustom-%s%>",
   4117  1.1  mrg 		 custom_builtin_name[index],
   4118  1.1  mrg 		 N2FPU_NAME (custom_code_index[N]));
   4119  1.1  mrg 	}
   4120  1.1  mrg       else
   4121  1.1  mrg 	{
   4122  1.1  mrg 	  /* Note that code conflicts between different __builtin_custom_xnxx
   4123  1.1  mrg 	     calls are not checked.  */
   4124  1.1  mrg 	}
   4125  1.1  mrg     }
   4126  1.1  mrg   else
   4127  1.1  mrg     gcc_unreachable ();
   4128  1.1  mrg 
   4129  1.1  mrg   custom_code_status[N] = status;
   4130  1.1  mrg   custom_code_index[N] = index;
   4131  1.1  mrg }
   4132  1.1  mrg 
   4133  1.1  mrg /* Mark a custom code as not in use.  */
   4134  1.1  mrg static void
   4135  1.1  mrg nios2_deregister_custom_code (unsigned int N)
   4136  1.1  mrg {
   4137  1.1  mrg   if (N <= 255)
   4138  1.1  mrg     {
   4139  1.1  mrg       custom_code_status[N] = CCS_UNUSED;
   4140  1.1  mrg       custom_code_index[N] = 0;
   4141  1.1  mrg     }
   4142  1.1  mrg }
   4143  1.1  mrg 
   4144  1.1  mrg /* Target attributes can affect per-function option state, so we need to
   4145  1.1  mrg    save/restore the custom code tracking info using the
   4146  1.1  mrg    TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks.  */
   4147  1.1  mrg 
   4148  1.1  mrg static void
   4149  1.1  mrg nios2_option_save (struct cl_target_option *ptr,
   4150  1.1  mrg 		   struct gcc_options *opts ATTRIBUTE_UNUSED,
   4151  1.1  mrg 		   struct gcc_options *opts_set ATTRIBUTE_UNUSED)
   4152  1.1  mrg {
   4153  1.1  mrg   unsigned int i;
   4154  1.1  mrg   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   4155  1.1  mrg     ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
   4156  1.1  mrg   memcpy (ptr->saved_custom_code_status, custom_code_status,
   4157  1.1  mrg 	  sizeof (custom_code_status));
   4158  1.1  mrg   memcpy (ptr->saved_custom_code_index, custom_code_index,
   4159  1.1  mrg 	  sizeof (custom_code_index));
   4160  1.1  mrg }
   4161  1.1  mrg 
   4162  1.1  mrg static void
   4163  1.1  mrg nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED,
   4164  1.1  mrg 		      struct gcc_options *opts_set ATTRIBUTE_UNUSED,
   4165  1.1  mrg 		      struct cl_target_option *ptr)
   4166  1.1  mrg {
   4167  1.1  mrg   unsigned int i;
   4168  1.1  mrg   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   4169  1.1  mrg     N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
   4170  1.1  mrg   memcpy (custom_code_status, ptr->saved_custom_code_status,
   4171  1.1  mrg 	  sizeof (custom_code_status));
   4172  1.1  mrg   memcpy (custom_code_index, ptr->saved_custom_code_index,
   4173  1.1  mrg 	  sizeof (custom_code_index));
   4174  1.1  mrg }
   4175  1.1  mrg 
   4176  1.1  mrg static bool
   4177  1.1  mrg nios2_can_inline_p (tree caller, tree callee)
   4178  1.1  mrg {
   4179  1.1  mrg   tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee);
   4180  1.1  mrg   tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller);
   4181  1.1  mrg   struct cl_target_option *callee_ptr, *caller_ptr;
   4182  1.1  mrg   unsigned int i;
   4183  1.1  mrg 
   4184  1.1  mrg   if (! callee_opts)
   4185  1.1  mrg     callee_opts = target_option_default_node;
   4186  1.1  mrg   if (! caller_opts)
   4187  1.1  mrg     caller_opts = target_option_default_node;
   4188  1.1  mrg 
   4189  1.1  mrg   /* If both caller and callee have attributes, assume that if the
   4190  1.1  mrg      pointer is different, the two functions have different target
   4191  1.1  mrg      options since build_target_option_node uses a hash table for the
   4192  1.1  mrg      options.  */
   4193  1.1  mrg   if (callee_opts == caller_opts)
   4194  1.1  mrg     return true;
   4195  1.1  mrg 
   4196  1.1  mrg   /* The only target options we recognize via function attributes are
   4197  1.1  mrg      those related to custom instructions.  If we failed the above test,
   4198  1.1  mrg      check that any custom instructions enabled in the callee are also
   4199  1.1  mrg      enabled with the same value in the caller.  */
   4200  1.1  mrg   callee_ptr = TREE_TARGET_OPTION (callee_opts);
   4201  1.1  mrg   caller_ptr = TREE_TARGET_OPTION (caller_opts);
   4202  1.1  mrg   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   4203  1.1  mrg     if (callee_ptr->saved_fpu_custom_code[i] != -1
   4204  1.1  mrg 	&& (callee_ptr->saved_fpu_custom_code[i]
   4205  1.1  mrg 	    != caller_ptr->saved_fpu_custom_code[i]))
   4206  1.1  mrg       return false;
   4207  1.1  mrg   return true;
   4208  1.1  mrg }
   4209  1.1  mrg 
   4210  1.1  mrg /* Inner function to process the attribute((target(...))), take an argument and
   4211  1.1  mrg    set the current options from the argument.  If we have a list, recursively
   4212  1.1  mrg    go over the list.  */
   4213  1.1  mrg 
   4214  1.1  mrg static bool
   4215  1.1  mrg nios2_valid_target_attribute_rec (tree args)
   4216  1.1  mrg {
   4217  1.1  mrg   if (TREE_CODE (args) == TREE_LIST)
   4218  1.1  mrg     {
   4219  1.1  mrg       bool ret = true;
   4220  1.1  mrg       for (; args; args = TREE_CHAIN (args))
   4221  1.1  mrg 	if (TREE_VALUE (args)
   4222  1.1  mrg 	    && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
   4223  1.1  mrg 	  ret = false;
   4224  1.1  mrg       return ret;
   4225  1.1  mrg     }
   4226  1.1  mrg   else if (TREE_CODE (args) == STRING_CST)
   4227  1.1  mrg     {
   4228  1.1  mrg       char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
   4229  1.1  mrg       while (argstr && *argstr != '\0')
   4230  1.1  mrg 	{
   4231  1.1  mrg 	  bool no_opt = false, end_p = false;
   4232  1.1  mrg 	  char *eq = NULL, *p;
   4233  1.1  mrg 	  while (ISSPACE (*argstr))
   4234  1.1  mrg 	    argstr++;
   4235  1.1  mrg 	  p = argstr;
   4236  1.1  mrg 	  while (*p != '\0' && *p != ',')
   4237  1.1  mrg 	    {
   4238  1.1  mrg 	      if (!eq && *p == '=')
   4239  1.1  mrg 		eq = p;
   4240  1.1  mrg 	      ++p;
   4241  1.1  mrg 	    }
   4242  1.1  mrg 	  if (*p == '\0')
   4243  1.1  mrg 	    end_p = true;
   4244  1.1  mrg 	  else
   4245  1.1  mrg 	    *p = '\0';
   4246  1.1  mrg 	  if (eq) *eq = '\0';
   4247  1.1  mrg 
   4248  1.1  mrg 	  if (startswith (argstr, "no-"))
   4249  1.1  mrg 	    {
   4250  1.1  mrg 	      no_opt = true;
   4251  1.1  mrg 	      argstr += 3;
   4252  1.1  mrg 	    }
   4253  1.1  mrg 	  if (startswith (argstr, "custom-fpu-cfg"))
   4254  1.1  mrg 	    {
   4255  1.1  mrg 	      char *end_eq = p;
   4256  1.1  mrg 	      if (no_opt)
   4257  1.1  mrg 		{
   4258  1.1  mrg 		  error ("%<custom-fpu-cfg%> option does not support %<no-%>");
   4259  1.1  mrg 		  return false;
   4260  1.1  mrg 		}
   4261  1.1  mrg 	      if (!eq)
   4262  1.1  mrg 		{
   4263  1.1  mrg 		  error ("%<custom-fpu-cfg%> option requires configuration "
   4264  1.1  mrg 			 "argument");
   4265  1.1  mrg 		  return false;
   4266  1.1  mrg 		}
   4267  1.1  mrg 	      /* Increment and skip whitespace.  */
   4268  1.1  mrg 	      while (ISSPACE (*(++eq))) ;
   4269  1.1  mrg 	      /* Decrement and skip to before any trailing whitespace.  */
   4270  1.1  mrg 	      while (ISSPACE (*(--end_eq))) ;
   4271  1.1  mrg 
   4272  1.1  mrg 	      nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true);
   4273  1.1  mrg 	    }
   4274  1.1  mrg 	  else if (startswith (argstr, "custom-"))
   4275  1.1  mrg 	    {
   4276  1.1  mrg 	      int code = -1;
   4277  1.1  mrg 	      unsigned int i;
   4278  1.1  mrg 	      for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
   4279  1.1  mrg 		if (startswith (argstr + 7, N2FPU_NAME (i)))
   4280  1.1  mrg 		  {
   4281  1.1  mrg 		    /* Found insn.  */
   4282  1.1  mrg 		    code = i;
   4283  1.1  mrg 		    break;
   4284  1.1  mrg 		  }
   4285  1.1  mrg 	      if (code >= 0)
   4286  1.1  mrg 		{
   4287  1.1  mrg 		  if (no_opt)
   4288  1.1  mrg 		    {
   4289  1.1  mrg 		      if (eq)
   4290  1.1  mrg 			{
   4291  1.1  mrg 			  error ("%<no-custom-%s%> does not accept arguments",
   4292  1.1  mrg 				 N2FPU_NAME (code));
   4293  1.1  mrg 			  return false;
   4294  1.1  mrg 			}
   4295  1.1  mrg 		      /* Disable option by setting to -1.  */
   4296  1.1  mrg 		      nios2_deregister_custom_code (N2FPU_N (code));
   4297  1.1  mrg 		      N2FPU_N (code) = -1;
   4298  1.1  mrg 		    }
   4299  1.1  mrg 		  else
   4300  1.1  mrg 		    {
   4301  1.1  mrg 		      char *t;
   4302  1.1  mrg 		      if (eq)
   4303  1.1  mrg 			while (ISSPACE (*(++eq))) ;
   4304  1.1  mrg 		      if (!eq || eq == p)
   4305  1.1  mrg 			{
   4306  1.1  mrg 			  error ("%<custom-%s=%> requires argument",
   4307  1.1  mrg 				 N2FPU_NAME (code));
   4308  1.1  mrg 			  return false;
   4309  1.1  mrg 			}
   4310  1.1  mrg 		      for (t = eq; t != p; ++t)
   4311  1.1  mrg 			{
   4312  1.1  mrg 			  if (ISSPACE (*t))
   4313  1.1  mrg 			    continue;
   4314  1.1  mrg 			  if (!ISDIGIT (*t))
   4315  1.1  mrg 			    {
   4316  1.1  mrg 			      error ("%<custom-%s=%> argument should be "
   4317  1.1  mrg 				     "a non-negative integer", N2FPU_NAME (code));
   4318  1.1  mrg 			      return false;
   4319  1.1  mrg 			    }
   4320  1.1  mrg 			}
   4321  1.1  mrg 		      /* Set option to argument.  */
   4322  1.1  mrg 		      N2FPU_N (code) = atoi (eq);
   4323  1.1  mrg 		      nios2_handle_custom_fpu_insn_option (code);
   4324  1.1  mrg 		    }
   4325  1.1  mrg 		}
   4326  1.1  mrg 	      else
   4327  1.1  mrg 		{
   4328  1.1  mrg 		  error ("%<custom-%s=%> is not recognized as FPU instruction",
   4329  1.1  mrg 			 argstr + 7);
   4330  1.1  mrg 		  return false;
   4331  1.1  mrg 		}
   4332  1.1  mrg 	    }
   4333  1.1  mrg 	  else
   4334  1.1  mrg 	    {
   4335  1.1  mrg 	      error ("invalid custom instruction option %qs", argstr);
   4336  1.1  mrg 	      return false;
   4337  1.1  mrg 	    }
   4338  1.1  mrg 
   4339  1.1  mrg 	  if (end_p)
   4340  1.1  mrg 	    break;
   4341  1.1  mrg 	  else
   4342  1.1  mrg 	    argstr = p + 1;
   4343  1.1  mrg 	}
   4344  1.1  mrg       return true;
   4345  1.1  mrg     }
   4346  1.1  mrg   else
   4347  1.1  mrg     gcc_unreachable ();
   4348  1.1  mrg }
   4349  1.1  mrg 
   4350  1.1  mrg /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL.  */
   4351  1.1  mrg 
   4352  1.1  mrg static tree
   4353  1.1  mrg nios2_valid_target_attribute_tree (tree args)
   4354  1.1  mrg {
   4355  1.1  mrg   if (!nios2_valid_target_attribute_rec (args))
   4356  1.1  mrg     return NULL_TREE;
   4357  1.1  mrg   nios2_custom_check_insns ();
   4358  1.1  mrg   return build_target_option_node (&global_options, &global_options_set);
   4359  1.1  mrg }
   4360  1.1  mrg 
   4361  1.1  mrg /* Hook to validate attribute((target("string"))).  */
   4362  1.1  mrg 
   4363  1.1  mrg static bool
   4364  1.1  mrg nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
   4365  1.1  mrg 				tree args, int ARG_UNUSED (flags))
   4366  1.1  mrg {
   4367  1.1  mrg   struct cl_target_option cur_target;
   4368  1.1  mrg   bool ret = true;
   4369  1.1  mrg   tree old_optimize
   4370  1.1  mrg     = build_optimization_node (&global_options, &global_options_set);
   4371  1.1  mrg   tree new_target, new_optimize;
   4372  1.1  mrg   tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
   4373  1.1  mrg 
   4374  1.1  mrg   /* If the function changed the optimization levels as well as setting target
   4375  1.1  mrg      options, start with the optimizations specified.  */
   4376  1.1  mrg   if (func_optimize && func_optimize != old_optimize)
   4377  1.1  mrg     cl_optimization_restore (&global_options, &global_options_set,
   4378  1.1  mrg 			     TREE_OPTIMIZATION (func_optimize));
   4379  1.1  mrg 
   4380  1.1  mrg   /* The target attributes may also change some optimization flags, so update
   4381  1.1  mrg      the optimization options if necessary.  */
   4382  1.1  mrg   cl_target_option_save (&cur_target, &global_options, &global_options_set);
   4383  1.1  mrg   new_target = nios2_valid_target_attribute_tree (args);
   4384  1.1  mrg   new_optimize = build_optimization_node (&global_options, &global_options_set);
   4385  1.1  mrg 
   4386  1.1  mrg   if (!new_target)
   4387  1.1  mrg     ret = false;
   4388  1.1  mrg 
   4389  1.1  mrg   else if (fndecl)
   4390  1.1  mrg     {
   4391  1.1  mrg       DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
   4392  1.1  mrg 
   4393  1.1  mrg       if (old_optimize != new_optimize)
   4394  1.1  mrg 	DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
   4395  1.1  mrg     }
   4396  1.1  mrg 
   4397  1.1  mrg   cl_target_option_restore (&global_options, &global_options_set, &cur_target);
   4398  1.1  mrg 
   4399  1.1  mrg   if (old_optimize != new_optimize)
   4400  1.1  mrg     cl_optimization_restore (&global_options, &global_options_set,
   4401  1.1  mrg 			     TREE_OPTIMIZATION (old_optimize));
   4402  1.1  mrg   return ret;
   4403  1.1  mrg }
   4404  1.1  mrg 
   4405  1.1  mrg /* Remember the last target of nios2_set_current_function.  */
   4406  1.1  mrg static GTY(()) tree nios2_previous_fndecl;
   4407  1.1  mrg 
   4408  1.1  mrg /* Establish appropriate back-end context for processing the function
   4409  1.1  mrg    FNDECL.  The argument might be NULL to indicate processing at top
   4410  1.1  mrg    level, outside of any function scope.  */
   4411  1.1  mrg static void
   4412  1.1  mrg nios2_set_current_function (tree fndecl)
   4413  1.1  mrg {
   4414  1.1  mrg   tree old_tree = (nios2_previous_fndecl
   4415  1.1  mrg 		   ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
   4416  1.1  mrg 		   : NULL_TREE);
   4417  1.1  mrg 
   4418  1.1  mrg   tree new_tree = (fndecl
   4419  1.1  mrg 		   ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
   4420  1.1  mrg 		   : NULL_TREE);
   4421  1.1  mrg 
   4422  1.1  mrg   if (fndecl && fndecl != nios2_previous_fndecl)
   4423  1.1  mrg     {
   4424  1.1  mrg       nios2_previous_fndecl = fndecl;
   4425  1.1  mrg       if (old_tree == new_tree)
   4426  1.1  mrg 	;
   4427  1.1  mrg 
   4428  1.1  mrg       else if (new_tree)
   4429  1.1  mrg 	{
   4430  1.1  mrg 	  cl_target_option_restore (&global_options, &global_options_set,
   4431  1.1  mrg 				    TREE_TARGET_OPTION (new_tree));
   4432  1.1  mrg 	  target_reinit ();
   4433  1.1  mrg 	}
   4434  1.1  mrg 
   4435  1.1  mrg       else if (old_tree)
   4436  1.1  mrg 	{
   4437  1.1  mrg 	  struct cl_target_option *def
   4438  1.1  mrg 	    = TREE_TARGET_OPTION (target_option_current_node);
   4439  1.1  mrg 
   4440  1.1  mrg 	  cl_target_option_restore (&global_options, &global_options_set, def);
   4441  1.1  mrg 	  target_reinit ();
   4442  1.1  mrg 	}
   4443  1.1  mrg     }
   4444  1.1  mrg }
   4445  1.1  mrg 
   4446  1.1  mrg /* Hook to validate the current #pragma GCC target and set the FPU custom
   4447  1.1  mrg    code option state.  If ARGS is NULL, then POP_TARGET is used to reset
   4448  1.1  mrg    the options.  */
   4449  1.1  mrg static bool
   4450  1.1  mrg nios2_pragma_target_parse (tree args, tree pop_target)
   4451  1.1  mrg {
   4452  1.1  mrg   tree cur_tree;
   4453  1.1  mrg   if (! args)
   4454  1.1  mrg     {
   4455  1.1  mrg       cur_tree = ((pop_target)
   4456  1.1  mrg 		  ? pop_target
   4457  1.1  mrg 		  : target_option_default_node);
   4458  1.1  mrg       cl_target_option_restore (&global_options, &global_options_set,
   4459  1.1  mrg 				TREE_TARGET_OPTION (cur_tree));
   4460  1.1  mrg     }
   4461  1.1  mrg   else
   4462  1.1  mrg     {
   4463  1.1  mrg       cur_tree = nios2_valid_target_attribute_tree (args);
   4464  1.1  mrg       if (!cur_tree)
   4465  1.1  mrg 	return false;
   4466  1.1  mrg     }
   4467  1.1  mrg 
   4468  1.1  mrg   target_option_current_node = cur_tree;
   4469  1.1  mrg   return true;
   4470  1.1  mrg }
   4471  1.1  mrg 
   4472  1.1  mrg /* Implement TARGET_MERGE_DECL_ATTRIBUTES.
   4473  1.1  mrg    We are just using this hook to add some additional error checking to
   4474  1.1  mrg    the default behavior.  GCC does not provide a target hook for merging
   4475  1.1  mrg    the target options, and only correctly handles merging empty vs non-empty
   4476  1.1  mrg    option data; see merge_decls() in c-decl.cc.
   4477  1.1  mrg    So here we require either that at least one of the decls has empty
   4478  1.1  mrg    target options, or that the target options/data be identical.  */
   4479  1.1  mrg static tree
   4480  1.1  mrg nios2_merge_decl_attributes (tree olddecl, tree newdecl)
   4481  1.1  mrg {
   4482  1.1  mrg   tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
   4483  1.1  mrg   tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
   4484  1.1  mrg   if (newopts && oldopts && newopts != oldopts)
   4485  1.1  mrg     {
   4486  1.1  mrg       tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
   4487  1.1  mrg       tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
   4488  1.1  mrg       if (oldtree && newtree && oldtree != newtree)
   4489  1.1  mrg 	{
   4490  1.1  mrg 	  struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
   4491  1.1  mrg 	  struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
   4492  1.1  mrg 	  if (olddata != newdata
   4493  1.1  mrg 	      && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
   4494  1.1  mrg 	    error ("%qE redeclared with conflicting %qs attributes",
   4495  1.1  mrg 		   DECL_NAME (newdecl), "target");
   4496  1.1  mrg 	}
   4497  1.1  mrg     }
   4498  1.1  mrg   return merge_attributes (DECL_ATTRIBUTES (olddecl),
   4499  1.1  mrg 			   DECL_ATTRIBUTES (newdecl));
   4500  1.1  mrg }
   4501  1.1  mrg 
   4502  1.1  mrg /* Implement TARGET_ASM_OUTPUT_MI_THUNK.  */
   4503  1.1  mrg static void
   4504  1.1  mrg nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   4505  1.1  mrg 			   HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
   4506  1.1  mrg 			   tree function)
   4507  1.1  mrg {
   4508  1.1  mrg   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   4509  1.1  mrg   rtx this_rtx, funexp;
   4510  1.1  mrg   rtx_insn *insn;
   4511  1.1  mrg 
   4512  1.1  mrg   /* Pretend to be a post-reload pass while generating rtl.  */
   4513  1.1  mrg   reload_completed = 1;
   4514  1.1  mrg 
   4515  1.1  mrg   if (flag_pic)
   4516  1.1  mrg     nios2_load_pic_register ();
   4517  1.1  mrg 
   4518  1.1  mrg   /* Mark the end of the (empty) prologue.  */
   4519  1.1  mrg   emit_note (NOTE_INSN_PROLOGUE_END);
   4520  1.1  mrg 
   4521  1.1  mrg   /* Find the "this" pointer.  If the function returns a structure,
   4522  1.1  mrg      the structure return pointer is in $5.  */
   4523  1.1  mrg   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
   4524  1.1  mrg     this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO + 1);
   4525  1.1  mrg   else
   4526  1.1  mrg     this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
   4527  1.1  mrg 
   4528  1.1  mrg   /* Add DELTA to THIS_RTX.  */
   4529  1.1  mrg   nios2_emit_add_constant (this_rtx, delta);
   4530  1.1  mrg 
   4531  1.1  mrg   /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX.  */
   4532  1.1  mrg   if (vcall_offset)
   4533  1.1  mrg     {
   4534  1.1  mrg       rtx tmp;
   4535  1.1  mrg 
   4536  1.1  mrg       tmp = gen_rtx_REG (Pmode, 2);
   4537  1.1  mrg       emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
   4538  1.1  mrg       nios2_emit_add_constant (tmp, vcall_offset);
   4539  1.1  mrg       emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
   4540  1.1  mrg       emit_insn (gen_add2_insn (this_rtx, tmp));
   4541  1.1  mrg     }
   4542  1.1  mrg 
   4543  1.1  mrg   /* Generate a tail call to the target function.  */
   4544  1.1  mrg   if (!TREE_USED (function))
   4545  1.1  mrg     {
   4546  1.1  mrg       assemble_external (function);
   4547  1.1  mrg       TREE_USED (function) = 1;
   4548  1.1  mrg     }
   4549  1.1  mrg   funexp = XEXP (DECL_RTL (function), 0);
   4550  1.1  mrg   /* Function address needs to be constructed under PIC,
   4551  1.1  mrg      provide r2 to use here.  */
   4552  1.1  mrg   nios2_adjust_call_address (&funexp, gen_rtx_REG (Pmode, 2));
   4553  1.1  mrg   insn = emit_call_insn (gen_sibcall_internal (funexp, const0_rtx));
   4554  1.1  mrg   SIBLING_CALL_P (insn) = 1;
   4555  1.1  mrg 
   4556  1.1  mrg   /* Run just enough of rest_of_compilation to get the insns emitted.
   4557  1.1  mrg      There's not really enough bulk here to make other passes such as
   4558  1.1  mrg      instruction scheduling worth while.  */
   4559  1.1  mrg   insn = get_insns ();
   4560  1.1  mrg   shorten_branches (insn);
   4561  1.1  mrg   assemble_start_function (thunk_fndecl, fnname);
   4562  1.1  mrg   final_start_function (insn, file, 1);
   4563  1.1  mrg   final (insn, file, 1);
   4564  1.1  mrg   final_end_function ();
   4565  1.1  mrg   assemble_end_function (thunk_fndecl, fnname);
   4566  1.1  mrg 
   4567  1.1  mrg   /* Stop pretending to be a post-reload pass.  */
   4568  1.1  mrg   reload_completed = 0;
   4569  1.1  mrg }
   4570  1.1  mrg 
   4571  1.1  mrg 
   4572  1.1  mrg /* Utility function to break a memory address into
   4573  1.1  mrg    base register + constant offset.  Return false if something
   4574  1.1  mrg    unexpected is seen.  */
   4575  1.1  mrg static bool
   4576  1.1  mrg split_mem_address (rtx addr, rtx *base_reg, rtx *offset)
   4577  1.1  mrg {
   4578  1.1  mrg   if (REG_P (addr))
   4579  1.1  mrg     {
   4580  1.1  mrg       *base_reg = addr;
   4581  1.1  mrg       *offset = const0_rtx;
   4582  1.1  mrg       return true;
   4583  1.1  mrg     }
   4584  1.1  mrg   else if (GET_CODE (addr) == PLUS)
   4585  1.1  mrg     {
   4586  1.1  mrg       *base_reg = XEXP (addr, 0);
   4587  1.1  mrg       *offset = XEXP (addr, 1);
   4588  1.1  mrg       return true;
   4589  1.1  mrg     }
   4590  1.1  mrg   return false;
   4591  1.1  mrg }
   4592  1.1  mrg 
   4593  1.1  mrg /* Splits out the operands of an ALU insn, places them in *LHS, *RHS1, *RHS2.  */
   4594  1.1  mrg static void
   4595  1.1  mrg split_alu_insn (rtx_insn *insn, rtx *lhs, rtx *rhs1, rtx *rhs2)
   4596  1.1  mrg {
   4597  1.1  mrg   rtx pat = PATTERN (insn);
   4598  1.1  mrg   gcc_assert (GET_CODE (pat) == SET);
   4599  1.1  mrg   *lhs = SET_DEST (pat);
   4600  1.1  mrg   *rhs1 = XEXP (SET_SRC (pat), 0);
   4601  1.1  mrg   if (GET_RTX_CLASS (GET_CODE (SET_SRC (pat))) != RTX_UNARY)
   4602  1.1  mrg     *rhs2 = XEXP (SET_SRC (pat), 1);
   4603  1.1  mrg   return;
   4604  1.1  mrg }
   4605  1.1  mrg 
   4606  1.1  mrg /* Returns true if OP is a REG and assigned a CDX reg.  */
   4607  1.1  mrg static bool
   4608  1.1  mrg cdxreg (rtx op)
   4609  1.1  mrg {
   4610  1.1  mrg   return REG_P (op) && (!reload_completed || CDX_REG_P (REGNO (op)));
   4611  1.1  mrg }
   4612  1.1  mrg 
   4613  1.1  mrg /* Returns true if OP is within range of CDX addi.n immediates.  */
   4614  1.1  mrg static bool
   4615  1.1  mrg cdx_add_immed (rtx op)
   4616  1.1  mrg {
   4617  1.1  mrg   if (CONST_INT_P (op))
   4618  1.1  mrg     {
   4619  1.1  mrg       HOST_WIDE_INT ival = INTVAL (op);
   4620  1.1  mrg       return ival <= 128 && ival > 0 && (ival & (ival - 1)) == 0;
   4621  1.1  mrg     }
   4622  1.1  mrg   return false;
   4623  1.1  mrg }
   4624  1.1  mrg 
   4625  1.1  mrg /* Returns true if OP is within range of CDX andi.n immediates.  */
   4626  1.1  mrg static bool
   4627  1.1  mrg cdx_and_immed (rtx op)
   4628  1.1  mrg {
   4629  1.1  mrg   if (CONST_INT_P (op))
   4630  1.1  mrg     {
   4631  1.1  mrg       HOST_WIDE_INT ival = INTVAL (op);
   4632  1.1  mrg       return (ival == 1 || ival == 2 || ival == 3 || ival == 4
   4633  1.1  mrg 	      || ival == 8 || ival == 0xf || ival == 0x10
   4634  1.1  mrg 	      || ival == 0x1f || ival == 0x20
   4635  1.1  mrg 	      || ival == 0x3f || ival == 0x7f
   4636  1.1  mrg 	      || ival == 0x80 || ival == 0xff || ival == 0x7ff
   4637  1.1  mrg 	      || ival == 0xff00 || ival == 0xffff);
   4638  1.1  mrg     }
   4639  1.1  mrg   return false;
   4640  1.1  mrg }
   4641  1.1  mrg 
   4642  1.1  mrg /* Returns true if OP is within range of CDX movi.n immediates.  */
   4643  1.1  mrg static bool
   4644  1.1  mrg cdx_mov_immed (rtx op)
   4645  1.1  mrg {
   4646  1.1  mrg   if (CONST_INT_P (op))
   4647  1.1  mrg     {
   4648  1.1  mrg       HOST_WIDE_INT ival = INTVAL (op);
   4649  1.1  mrg       return ((ival >= 0 && ival <= 124)
   4650  1.1  mrg 	      || ival == 0xff || ival == -2 || ival == -1);
   4651  1.1  mrg     }
   4652  1.1  mrg   return false;
   4653  1.1  mrg }
   4654  1.1  mrg 
   4655  1.1  mrg /* Returns true if OP is within range of CDX slli.n/srli.n immediates.  */
   4656  1.1  mrg static bool
   4657  1.1  mrg cdx_shift_immed (rtx op)
   4658  1.1  mrg {
   4659  1.1  mrg   if (CONST_INT_P (op))
   4660  1.1  mrg     {
   4661  1.1  mrg       HOST_WIDE_INT ival = INTVAL (op);
   4662  1.1  mrg       return (ival == 1 || ival == 2 || ival == 3 || ival == 8
   4663  1.1  mrg 	      || ival == 12 || ival == 16 || ival == 24
   4664  1.1  mrg 	      || ival == 31);
   4665  1.1  mrg     }
   4666  1.1  mrg   return false;
   4667  1.1  mrg }
   4668  1.1  mrg 
   4669  1.1  mrg 
   4670  1.1  mrg 
   4671  1.1  mrg /* Classification of different kinds of add instructions.  */
   4672  1.1  mrg enum nios2_add_insn_kind {
   4673  1.1  mrg   nios2_add_n_kind,
   4674  1.1  mrg   nios2_addi_n_kind,
   4675  1.1  mrg   nios2_subi_n_kind,
   4676  1.1  mrg   nios2_spaddi_n_kind,
   4677  1.1  mrg   nios2_spinci_n_kind,
   4678  1.1  mrg   nios2_spdeci_n_kind,
   4679  1.1  mrg   nios2_add_kind,
   4680  1.1  mrg   nios2_addi_kind
   4681  1.1  mrg };
   4682  1.1  mrg 
   4683  1.1  mrg static const char *nios2_add_insn_names[] = {
   4684  1.1  mrg   "add.n", "addi.n", "subi.n", "spaddi.n",  "spinci.n", "spdeci.n",
   4685  1.1  mrg   "add", "addi" };
   4686  1.1  mrg static bool nios2_add_insn_narrow[] = {
   4687  1.1  mrg   true, true, true, true, true, true,
   4688  1.1  mrg   false, false};
   4689  1.1  mrg 
   4690  1.1  mrg /* Function to classify kinds of add instruction patterns.  */
   4691  1.1  mrg static enum nios2_add_insn_kind
   4692  1.1  mrg nios2_add_insn_classify (rtx_insn *insn ATTRIBUTE_UNUSED,
   4693  1.1  mrg 			 rtx lhs, rtx rhs1, rtx rhs2)
   4694  1.1  mrg {
   4695  1.1  mrg   if (TARGET_HAS_CDX)
   4696  1.1  mrg     {
   4697  1.1  mrg       if (cdxreg (lhs) && cdxreg (rhs1))
   4698  1.1  mrg 	{
   4699  1.1  mrg 	  if (cdxreg (rhs2))
   4700  1.1  mrg 	    return nios2_add_n_kind;
   4701  1.1  mrg 	  if (CONST_INT_P (rhs2))
   4702  1.1  mrg 	    {
   4703  1.1  mrg 	      HOST_WIDE_INT ival = INTVAL (rhs2);
   4704  1.1  mrg 	      if (ival > 0 && cdx_add_immed (rhs2))
   4705  1.1  mrg 		return nios2_addi_n_kind;
   4706  1.1  mrg 	      if (ival < 0 && cdx_add_immed (GEN_INT (-ival)))
   4707  1.1  mrg 		return nios2_subi_n_kind;
   4708  1.1  mrg 	    }
   4709  1.1  mrg 	}
   4710  1.1  mrg       else if (rhs1 == stack_pointer_rtx
   4711  1.1  mrg 	       && CONST_INT_P (rhs2))
   4712  1.1  mrg 	{
   4713  1.1  mrg 	  HOST_WIDE_INT imm7 = INTVAL (rhs2) >> 2;
   4714  1.1  mrg 	  HOST_WIDE_INT rem = INTVAL (rhs2) & 3;
   4715  1.1  mrg 	  if (rem == 0 && (imm7 & ~0x7f) == 0)
   4716  1.1  mrg 	    {
   4717  1.1  mrg 	      if (cdxreg (lhs))
   4718  1.1  mrg 		return nios2_spaddi_n_kind;
   4719  1.1  mrg 	      if (lhs == stack_pointer_rtx)
   4720  1.1  mrg 		return nios2_spinci_n_kind;
   4721  1.1  mrg 	    }
   4722  1.1  mrg 	  imm7 = -INTVAL(rhs2) >> 2;
   4723  1.1  mrg 	  rem = -INTVAL (rhs2) & 3;
   4724  1.1  mrg 	  if (lhs == stack_pointer_rtx
   4725  1.1  mrg 	      && rem == 0 && (imm7 & ~0x7f) == 0)
   4726  1.1  mrg 	    return nios2_spdeci_n_kind;
   4727  1.1  mrg 	}
   4728  1.1  mrg     }
   4729  1.1  mrg   return ((REG_P (rhs2) || rhs2 == const0_rtx)
   4730  1.1  mrg 	  ? nios2_add_kind : nios2_addi_kind);
   4731  1.1  mrg }
   4732  1.1  mrg 
   4733  1.1  mrg /* Emit assembly language for the different kinds of add instructions.  */
   4734  1.1  mrg const char*
   4735  1.1  mrg nios2_add_insn_asm (rtx_insn *insn, rtx *operands)
   4736  1.1  mrg {
   4737  1.1  mrg   static char buf[256];
   4738  1.1  mrg   int ln = 256;
   4739  1.1  mrg   enum nios2_add_insn_kind kind
   4740  1.1  mrg     = nios2_add_insn_classify (insn, operands[0], operands[1], operands[2]);
   4741  1.1  mrg   if (kind == nios2_subi_n_kind)
   4742  1.1  mrg     snprintf (buf, ln, "subi.n\t%%0, %%1, %d", (int) -INTVAL (operands[2]));
   4743  1.1  mrg   else if (kind == nios2_spaddi_n_kind)
   4744  1.1  mrg     snprintf (buf, ln, "spaddi.n\t%%0, %%2");
   4745  1.1  mrg   else if (kind == nios2_spinci_n_kind)
   4746  1.1  mrg     snprintf (buf, ln, "spinci.n\t%%2");
   4747  1.1  mrg   else if (kind == nios2_spdeci_n_kind)
   4748  1.1  mrg     snprintf (buf, ln, "spdeci.n\t%d", (int) -INTVAL (operands[2]));
   4749  1.1  mrg   else
   4750  1.1  mrg     snprintf (buf, ln, "%s\t%%0, %%1, %%z2", nios2_add_insn_names[(int)kind]);
   4751  1.1  mrg   return buf;
   4752  1.1  mrg }
   4753  1.1  mrg 
   4754  1.1  mrg /* This routine, which the default "length" attribute computation is
   4755  1.1  mrg    based on, encapsulates information about all the cases where CDX
   4756  1.1  mrg    provides a narrow 2-byte instruction form.  */
   4757  1.1  mrg bool
   4758  1.1  mrg nios2_cdx_narrow_form_p (rtx_insn *insn)
   4759  1.1  mrg {
   4760  1.1  mrg   rtx pat, lhs, rhs1 = NULL_RTX, rhs2 = NULL_RTX;
   4761  1.1  mrg   enum attr_type type;
   4762  1.1  mrg   if (!TARGET_HAS_CDX)
   4763  1.1  mrg     return false;
   4764  1.1  mrg   type = get_attr_type (insn);
   4765  1.1  mrg   pat = PATTERN (insn);
   4766  1.1  mrg   gcc_assert (reload_completed);
   4767  1.1  mrg   switch (type)
   4768  1.1  mrg     {
   4769  1.1  mrg     case TYPE_CONTROL:
   4770  1.1  mrg       if (GET_CODE (pat) == SIMPLE_RETURN)
   4771  1.1  mrg 	return true;
   4772  1.1  mrg       if (GET_CODE (pat) == PARALLEL)
   4773  1.1  mrg 	pat = XVECEXP (pat, 0, 0);
   4774  1.1  mrg       if (GET_CODE (pat) == SET)
   4775  1.1  mrg 	pat = SET_SRC (pat);
   4776  1.1  mrg       if (GET_CODE (pat) == IF_THEN_ELSE)
   4777  1.1  mrg 	{
   4778  1.1  mrg 	  /* Conditional branch patterns; for these we
   4779  1.1  mrg 	     only check the comparison to find beqz.n/bnez.n cases.
   4780  1.1  mrg 	     For the 'nios2_cbranch' pattern, we cannot also check
   4781  1.1  mrg 	     the branch range here. That will be done at the md
   4782  1.1  mrg 	     pattern "length" attribute computation.  */
   4783  1.1  mrg 	  rtx cmp = XEXP (pat, 0);
   4784  1.1  mrg 	  return ((GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE)
   4785  1.1  mrg 		  && cdxreg (XEXP (cmp, 0))
   4786  1.1  mrg 		  && XEXP (cmp, 1) == const0_rtx);
   4787  1.1  mrg 	}
   4788  1.1  mrg       if (GET_CODE (pat) == TRAP_IF)
   4789  1.1  mrg 	/* trap.n is always usable.  */
   4790  1.1  mrg 	return true;
   4791  1.1  mrg       if (GET_CODE (pat) == CALL)
   4792  1.1  mrg 	pat = XEXP (XEXP (pat, 0), 0);
   4793  1.1  mrg       if (REG_P (pat))
   4794  1.1  mrg 	/* Control instructions taking a register operand are indirect
   4795  1.1  mrg 	   jumps and calls.  The CDX instructions have a 5-bit register
   4796  1.1  mrg 	   field so any reg is valid.  */
   4797  1.1  mrg 	return true;
   4798  1.1  mrg       else
   4799  1.1  mrg 	{
   4800  1.1  mrg 	  gcc_assert (!insn_variable_length_p (insn));
   4801  1.1  mrg 	  return false;
   4802  1.1  mrg 	}
   4803  1.1  mrg     case TYPE_ADD:
   4804  1.1  mrg       {
   4805  1.1  mrg 	enum nios2_add_insn_kind kind;
   4806  1.1  mrg 	split_alu_insn (insn, &lhs, &rhs1, &rhs2);
   4807  1.1  mrg 	kind = nios2_add_insn_classify (insn, lhs, rhs1, rhs2);
   4808  1.1  mrg 	return nios2_add_insn_narrow[(int)kind];
   4809  1.1  mrg       }
   4810  1.1  mrg     case TYPE_LD:
   4811  1.1  mrg       {
   4812  1.1  mrg 	bool ret;
   4813  1.1  mrg 	HOST_WIDE_INT offset, rem = 0;
   4814  1.1  mrg 	rtx addr, reg = SET_DEST (pat), mem = SET_SRC (pat);
   4815  1.1  mrg 	if (GET_CODE (mem) == SIGN_EXTEND)
   4816  1.1  mrg 	  /* No CDX form for sign-extended load.  */
   4817  1.1  mrg 	  return false;
   4818  1.1  mrg 	if (GET_CODE (mem) == ZERO_EXTEND)
   4819  1.1  mrg 	  /* The load alternatives in the zero_extend* patterns.  */
   4820  1.1  mrg 	  mem = XEXP (mem, 0);
   4821  1.1  mrg 	if (MEM_P (mem))
   4822  1.1  mrg 	  {
   4823  1.1  mrg 	    /* ldxio.  */
   4824  1.1  mrg 	    if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE)
   4825  1.1  mrg 		|| TARGET_BYPASS_CACHE)
   4826  1.1  mrg 	      return false;
   4827  1.1  mrg 	    addr = XEXP (mem, 0);
   4828  1.1  mrg 	    /* GP-based and R0-based references are never narrow.  */
   4829  1.1  mrg 	    if (gprel_constant_p (addr) || r0rel_constant_p (addr))
   4830  1.1  mrg 		return false;
   4831  1.1  mrg 	    /* %lo requires a 16-bit relocation and is never narrow.  */
   4832  1.1  mrg 	    if (GET_CODE (addr) == LO_SUM)
   4833  1.1  mrg 	      return false;
   4834  1.1  mrg 	    ret = split_mem_address (addr, &rhs1, &rhs2);
   4835  1.1  mrg 	    gcc_assert (ret);
   4836  1.1  mrg 	  }
   4837  1.1  mrg 	else
   4838  1.1  mrg 	  return false;
   4839  1.1  mrg 
   4840  1.1  mrg 	offset = INTVAL (rhs2);
   4841  1.1  mrg 	if (GET_MODE (mem) == SImode)
   4842  1.1  mrg 	  {
   4843  1.1  mrg 	    rem = offset & 3;
   4844  1.1  mrg 	    offset >>= 2;
   4845  1.1  mrg 	    /* ldwsp.n case.  */
   4846  1.1  mrg 	    if (rtx_equal_p (rhs1, stack_pointer_rtx)
   4847  1.1  mrg 		&& rem == 0 && (offset & ~0x1f) == 0)
   4848  1.1  mrg 	      return true;
   4849  1.1  mrg 	  }
   4850  1.1  mrg 	else if (GET_MODE (mem) == HImode)
   4851  1.1  mrg 	  {
   4852  1.1  mrg 	    rem = offset & 1;
   4853  1.1  mrg 	    offset >>= 1;
   4854  1.1  mrg 	  }
   4855  1.1  mrg 	/* ldbu.n, ldhu.n, ldw.n cases.  */
   4856  1.1  mrg 	return (cdxreg (reg) && cdxreg (rhs1)
   4857  1.1  mrg 		&& rem == 0 && (offset & ~0xf) == 0);
   4858  1.1  mrg       }
   4859  1.1  mrg     case TYPE_ST:
   4860  1.1  mrg       if (GET_CODE (pat) == PARALLEL)
   4861  1.1  mrg 	/* stex, stsex.  */
   4862  1.1  mrg 	return false;
   4863  1.1  mrg       else
   4864  1.1  mrg 	{
   4865  1.1  mrg 	  bool ret;
   4866  1.1  mrg 	  HOST_WIDE_INT offset, rem = 0;
   4867  1.1  mrg 	  rtx addr, reg = SET_SRC (pat), mem = SET_DEST (pat);
   4868  1.1  mrg 	  if (!MEM_P (mem))
   4869  1.1  mrg 	    return false;
   4870  1.1  mrg 	  /* stxio.  */
   4871  1.1  mrg 	  if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE)
   4872  1.1  mrg 	      || TARGET_BYPASS_CACHE)
   4873  1.1  mrg 	    return false;
   4874  1.1  mrg 	  addr = XEXP (mem, 0);
   4875  1.1  mrg 	  /* GP-based and r0-based references are never narrow.  */
   4876  1.1  mrg 	  if (gprel_constant_p (addr) || r0rel_constant_p (addr))
   4877  1.1  mrg 	    return false;
   4878  1.1  mrg 	  /* %lo requires a 16-bit relocation and is never narrow.  */
   4879  1.1  mrg 	  if (GET_CODE (addr) == LO_SUM)
   4880  1.1  mrg 	    return false;
   4881  1.1  mrg 	  ret = split_mem_address (addr, &rhs1, &rhs2);
   4882  1.1  mrg 	  gcc_assert (ret);
   4883  1.1  mrg 	  offset = INTVAL (rhs2);
   4884  1.1  mrg 	  if (GET_MODE (mem) == SImode)
   4885  1.1  mrg 	    {
   4886  1.1  mrg 	      rem = offset & 3;
   4887  1.1  mrg 	      offset >>= 2;
   4888  1.1  mrg 	      /* stwsp.n case.  */
   4889  1.1  mrg 	      if (rtx_equal_p (rhs1, stack_pointer_rtx)
   4890  1.1  mrg 		  && rem == 0 && (offset & ~0x1f) == 0)
   4891  1.1  mrg 		return true;
   4892  1.1  mrg 	      /* stwz.n case.  */
   4893  1.1  mrg 	      else if (reg == const0_rtx && cdxreg (rhs1)
   4894  1.1  mrg 		       && rem == 0 && (offset & ~0x3f) == 0)
   4895  1.1  mrg 		return true;
   4896  1.1  mrg 	    }
   4897  1.1  mrg 	  else if (GET_MODE (mem) == HImode)
   4898  1.1  mrg 	    {
   4899  1.1  mrg 	      rem = offset & 1;
   4900  1.1  mrg 	      offset >>= 1;
   4901  1.1  mrg 	    }
   4902  1.1  mrg 	  else
   4903  1.1  mrg 	    {
   4904  1.1  mrg 	      gcc_assert (GET_MODE (mem) == QImode);
   4905  1.1  mrg 	      /* stbz.n case.  */
   4906  1.1  mrg 	      if (reg == const0_rtx && cdxreg (rhs1)
   4907  1.1  mrg 		  && (offset & ~0x3f) == 0)
   4908  1.1  mrg 		return true;
   4909  1.1  mrg 	    }
   4910  1.1  mrg 
   4911  1.1  mrg 	  /* stbu.n, sthu.n, stw.n cases.  */
   4912  1.1  mrg 	  return (cdxreg (reg) && cdxreg (rhs1)
   4913  1.1  mrg 		  && rem == 0 && (offset & ~0xf) == 0);
   4914  1.1  mrg 	}
   4915  1.1  mrg     case TYPE_MOV:
   4916  1.1  mrg       lhs = SET_DEST (pat);
   4917  1.1  mrg       rhs1 = SET_SRC (pat);
   4918  1.1  mrg       if (CONST_INT_P (rhs1))
   4919  1.1  mrg 	return (cdxreg (lhs) && cdx_mov_immed (rhs1));
   4920  1.1  mrg       gcc_assert (REG_P (lhs) && REG_P (rhs1));
   4921  1.1  mrg       return true;
   4922  1.1  mrg 
   4923  1.1  mrg     case TYPE_AND:
   4924  1.1  mrg       /* Some zero_extend* alternatives are and insns.  */
   4925  1.1  mrg       if (GET_CODE (SET_SRC (pat)) == ZERO_EXTEND)
   4926  1.1  mrg 	return (cdxreg (SET_DEST (pat))
   4927  1.1  mrg 		&& cdxreg (XEXP (SET_SRC (pat), 0)));
   4928  1.1  mrg       split_alu_insn (insn, &lhs, &rhs1, &rhs2);
   4929  1.1  mrg       if (CONST_INT_P (rhs2))
   4930  1.1  mrg 	return (cdxreg (lhs) && cdxreg (rhs1) && cdx_and_immed (rhs2));
   4931  1.1  mrg       return (cdxreg (lhs) && cdxreg (rhs2)
   4932  1.1  mrg 	      && (!reload_completed || rtx_equal_p (lhs, rhs1)));
   4933  1.1  mrg 
   4934  1.1  mrg     case TYPE_OR:
   4935  1.1  mrg     case TYPE_XOR:
   4936  1.1  mrg       /* Note the two-address limitation for CDX form.  */
   4937  1.1  mrg       split_alu_insn (insn, &lhs, &rhs1, &rhs2);
   4938  1.1  mrg       return (cdxreg (lhs) && cdxreg (rhs2)
   4939  1.1  mrg 	      && (!reload_completed || rtx_equal_p (lhs, rhs1)));
   4940  1.1  mrg 
   4941  1.1  mrg     case TYPE_SUB:
   4942  1.1  mrg       split_alu_insn (insn, &lhs, &rhs1, &rhs2);
   4943  1.1  mrg       return (cdxreg (lhs) && cdxreg (rhs1) && cdxreg (rhs2));
   4944  1.1  mrg 
   4945  1.1  mrg     case TYPE_NEG:
   4946  1.1  mrg     case TYPE_NOT:
   4947  1.1  mrg       split_alu_insn (insn, &lhs, &rhs1, NULL);
   4948  1.1  mrg       return (cdxreg (lhs) && cdxreg (rhs1));
   4949  1.1  mrg 
   4950  1.1  mrg     case TYPE_SLL:
   4951  1.1  mrg     case TYPE_SRL:
   4952  1.1  mrg       split_alu_insn (insn, &lhs, &rhs1, &rhs2);
   4953  1.1  mrg       return (cdxreg (lhs)
   4954  1.1  mrg 	      && ((cdxreg (rhs1) && cdx_shift_immed (rhs2))
   4955  1.1  mrg 		  || (cdxreg (rhs2)
   4956  1.1  mrg 		      && (!reload_completed || rtx_equal_p (lhs, rhs1)))));
   4957  1.1  mrg     case TYPE_NOP:
   4958  1.1  mrg     case TYPE_PUSH:
   4959  1.1  mrg     case TYPE_POP:
   4960  1.1  mrg       return true;
   4961  1.1  mrg     default:
   4962  1.1  mrg       break;
   4963  1.1  mrg     }
   4964  1.1  mrg   return false;
   4965  1.1  mrg }
   4966  1.1  mrg 
   4967  1.1  mrg /* Main function to implement the pop_operation predicate that
   4968  1.1  mrg    check pop.n insn pattern integrity.  The CDX pop.n patterns mostly
   4969  1.1  mrg    hardcode the restored registers, so the main checking is for the
   4970  1.1  mrg    SP offsets.  */
   4971  1.1  mrg bool
   4972  1.1  mrg pop_operation_p (rtx op)
   4973  1.1  mrg {
   4974  1.1  mrg   int i;
   4975  1.1  mrg   HOST_WIDE_INT last_offset = -1, len = XVECLEN (op, 0);
   4976  1.1  mrg   rtx base_reg, offset;
   4977  1.1  mrg 
   4978  1.1  mrg   if (len < 3 /* At least has a return, SP-update, and RA restore.  */
   4979  1.1  mrg       || GET_CODE (XVECEXP (op, 0, 0)) != RETURN
   4980  1.1  mrg       || !base_reg_adjustment_p (XVECEXP (op, 0, 1), &base_reg, &offset)
   4981  1.1  mrg       || !rtx_equal_p (base_reg, stack_pointer_rtx)
   4982  1.1  mrg       || !CONST_INT_P (offset)
   4983  1.1  mrg       || (INTVAL (offset) & 3) != 0)
   4984  1.1  mrg     return false;
   4985  1.1  mrg 
   4986  1.1  mrg   for (i = len - 1; i > 1; i--)
   4987  1.1  mrg     {
   4988  1.1  mrg       rtx set = XVECEXP (op, 0, i);
   4989  1.1  mrg       rtx curr_base_reg, curr_offset;
   4990  1.1  mrg 
   4991  1.1  mrg       if (GET_CODE (set) != SET || !MEM_P (SET_SRC (set))
   4992  1.1  mrg 	  || !split_mem_address (XEXP (SET_SRC (set), 0),
   4993  1.1  mrg 				 &curr_base_reg, &curr_offset)
   4994  1.1  mrg 	  || !rtx_equal_p (base_reg, curr_base_reg)
   4995  1.1  mrg 	  || !CONST_INT_P (curr_offset))
   4996  1.1  mrg 	return false;
   4997  1.1  mrg       if (i == len - 1)
   4998  1.1  mrg 	{
   4999  1.1  mrg 	  last_offset = INTVAL (curr_offset);
   5000  1.1  mrg 	  if ((last_offset & 3) != 0 || last_offset > 60)
   5001  1.1  mrg 	    return false;
   5002  1.1  mrg 	}
   5003  1.1  mrg       else
   5004  1.1  mrg 	{
   5005  1.1  mrg 	  last_offset += 4;
   5006  1.1  mrg 	  if (INTVAL (curr_offset) != last_offset)
   5007  1.1  mrg 	    return false;
   5008  1.1  mrg 	}
   5009  1.1  mrg     }
   5010  1.1  mrg   if (last_offset < 0 || last_offset + 4 != INTVAL (offset))
   5011  1.1  mrg     return false;
   5012  1.1  mrg 
   5013  1.1  mrg   return true;
   5014  1.1  mrg }
   5015  1.1  mrg 
   5016  1.1  mrg 
   5017  1.1  mrg /* Masks of registers that are valid for CDX ldwm/stwm instructions.
   5018  1.1  mrg    The instruction can encode subsets drawn from either R2-R13 or
   5019  1.1  mrg    R14-R23 + FP + RA.  */
   5020  1.1  mrg #define CDX_LDSTWM_VALID_REGS_0 0x00003ffc
   5021  1.1  mrg #define CDX_LDSTWM_VALID_REGS_1 0x90ffc000
   5022  1.1  mrg 
   5023  1.1  mrg static bool
   5024  1.1  mrg nios2_ldstwm_regset_p (unsigned int regno, unsigned int *regset)
   5025  1.1  mrg {
   5026  1.1  mrg   if (*regset == 0)
   5027  1.1  mrg     {
   5028  1.1  mrg       if (CDX_LDSTWM_VALID_REGS_0 & (1 << regno))
   5029  1.1  mrg 	*regset = CDX_LDSTWM_VALID_REGS_0;
   5030  1.1  mrg       else if (CDX_LDSTWM_VALID_REGS_1 & (1 << regno))
   5031  1.1  mrg 	*regset = CDX_LDSTWM_VALID_REGS_1;
   5032  1.1  mrg       else
   5033  1.1  mrg 	return false;
   5034  1.1  mrg       return true;
   5035  1.1  mrg     }
   5036  1.1  mrg   else
   5037  1.1  mrg     return (*regset & (1 << regno)) != 0;
   5038  1.1  mrg }
   5039  1.1  mrg 
   5040  1.1  mrg /* Main function to implement ldwm_operation/stwm_operation
   5041  1.1  mrg    predicates that check ldwm/stwm insn pattern integrity.  */
   5042  1.1  mrg bool
   5043  1.1  mrg ldstwm_operation_p (rtx op, bool load_p)
   5044  1.1  mrg {
   5045  1.1  mrg   int start, i, end = XVECLEN (op, 0) - 1, last_regno = -1;
   5046  1.1  mrg   unsigned int regset = 0;
   5047  1.1  mrg   rtx base_reg, offset;
   5048  1.1  mrg   rtx first_elt = XVECEXP (op, 0, 0);
   5049  1.1  mrg   bool inc_p = true;
   5050  1.1  mrg   bool wb_p = base_reg_adjustment_p (first_elt, &base_reg, &offset);
   5051  1.1  mrg   if (GET_CODE (XVECEXP (op, 0, end)) == RETURN)
   5052  1.1  mrg     end--;
   5053  1.1  mrg   start = wb_p ? 1 : 0;
   5054  1.1  mrg   for (i = start; i <= end; i++)
   5055  1.1  mrg     {
   5056  1.1  mrg       int regno;
   5057  1.1  mrg       rtx reg, mem, elt = XVECEXP (op, 0, i);
   5058  1.1  mrg       /* Return early if not a SET at all.  */
   5059  1.1  mrg       if (GET_CODE (elt) != SET)
   5060  1.1  mrg 	return false;
   5061  1.1  mrg       reg = load_p ? SET_DEST (elt) : SET_SRC (elt);
   5062  1.1  mrg       mem = load_p ? SET_SRC (elt) : SET_DEST (elt);
   5063  1.1  mrg       if (!REG_P (reg) || !MEM_P (mem))
   5064  1.1  mrg 	return false;
   5065  1.1  mrg       regno = REGNO (reg);
   5066  1.1  mrg       if (!nios2_ldstwm_regset_p (regno, &regset))
   5067  1.1  mrg 	return false;
   5068  1.1  mrg       /* If no writeback to determine direction, use offset of first MEM.  */
   5069  1.1  mrg       if (wb_p)
   5070  1.1  mrg 	inc_p = INTVAL (offset) > 0;
   5071  1.1  mrg       else if (i == start)
   5072  1.1  mrg 	{
   5073  1.1  mrg 	  rtx first_base, first_offset;
   5074  1.1  mrg 	  if (!split_mem_address (XEXP (mem, 0),
   5075  1.1  mrg 				  &first_base, &first_offset))
   5076  1.1  mrg 	    return false;
   5077  1.1  mrg 	  if (!REG_P (first_base) || !CONST_INT_P (first_offset))
   5078  1.1  mrg 	    return false;
   5079  1.1  mrg 	  base_reg = first_base;
   5080  1.1  mrg 	  inc_p = INTVAL (first_offset) >= 0;
   5081  1.1  mrg 	}
   5082  1.1  mrg       /* Ensure that the base register is not loaded into.  */
   5083  1.1  mrg       if (load_p && regno == (int) REGNO (base_reg))
   5084  1.1  mrg 	return false;
   5085  1.1  mrg       /* Check for register order inc/dec integrity.  */
   5086  1.1  mrg       if (last_regno >= 0)
   5087  1.1  mrg 	{
   5088  1.1  mrg 	  if (inc_p && last_regno >= regno)
   5089  1.1  mrg 	    return false;
   5090  1.1  mrg 	  if (!inc_p && last_regno <= regno)
   5091  1.1  mrg 	    return false;
   5092  1.1  mrg 	}
   5093  1.1  mrg       last_regno = regno;
   5094  1.1  mrg     }
   5095  1.1  mrg   return true;
   5096  1.1  mrg }
   5097  1.1  mrg 
   5098  1.1  mrg /* Helper for nios2_ldst_parallel, for generating a parallel vector
   5099  1.1  mrg    SET element.  */
   5100  1.1  mrg static rtx
   5101  1.1  mrg gen_ldst (bool load_p, int regno, rtx base_mem, int offset)
   5102  1.1  mrg {
   5103  1.1  mrg   rtx reg = gen_rtx_REG (SImode, regno);
   5104  1.1  mrg   rtx mem = adjust_address_nv (base_mem, SImode, offset);
   5105  1.1  mrg   return gen_rtx_SET (load_p ? reg : mem,
   5106  1.1  mrg 		      load_p ? mem : reg);
   5107  1.1  mrg }
   5108  1.1  mrg 
   5109  1.1  mrg /* A general routine for creating the body RTL pattern of
   5110  1.1  mrg    ldwm/stwm/push.n/pop.n insns.
   5111  1.1  mrg    LOAD_P: true/false for load/store direction.
   5112  1.1  mrg    REG_INC_P: whether registers are incrementing/decrementing in the
   5113  1.1  mrg    *RTL vector* (not necessarily the order defined in the ISA specification).
   5114  1.1  mrg    OFFSET_INC_P: Same as REG_INC_P, but for the memory offset order.
   5115  1.1  mrg    BASE_MEM: starting MEM.
   5116  1.1  mrg    BASE_UPDATE: amount to update base register; zero means no writeback.
   5117  1.1  mrg    REGMASK: register mask to load/store.
   5118  1.1  mrg    RET_P: true if to tag a (return) element at the end.
   5119  1.1  mrg 
   5120  1.1  mrg    Note that this routine does not do any checking. It's the job of the
   5121  1.1  mrg    caller to do the right thing, and the insn patterns to do the
   5122  1.1  mrg    safe-guarding.  */
   5123  1.1  mrg static rtx
   5124  1.1  mrg nios2_ldst_parallel (bool load_p, bool reg_inc_p, bool offset_inc_p,
   5125  1.1  mrg 		     rtx base_mem, int base_update,
   5126  1.1  mrg 		     unsigned HOST_WIDE_INT regmask, bool ret_p)
   5127  1.1  mrg {
   5128  1.1  mrg   rtvec p;
   5129  1.1  mrg   int regno, b = 0, i = 0, n = 0, len = popcount_hwi (regmask);
   5130  1.1  mrg   if (ret_p) len++, i++, b++;
   5131  1.1  mrg   if (base_update != 0) len++, i++;
   5132  1.1  mrg   p = rtvec_alloc (len);
   5133  1.1  mrg   for (regno = (reg_inc_p ? 0 : 31);
   5134  1.1  mrg        regno != (reg_inc_p ? 32 : -1);
   5135  1.1  mrg        regno += (reg_inc_p ? 1 : -1))
   5136  1.1  mrg     if ((regmask & (1 << regno)) != 0)
   5137  1.1  mrg       {
   5138  1.1  mrg 	int offset = (offset_inc_p ? 4 : -4) * n++;
   5139  1.1  mrg 	RTVEC_ELT (p, i++) = gen_ldst (load_p, regno, base_mem, offset);
   5140  1.1  mrg       }
   5141  1.1  mrg   if (ret_p)
   5142  1.1  mrg     RTVEC_ELT (p, 0) = ret_rtx;
   5143  1.1  mrg   if (base_update != 0)
   5144  1.1  mrg     {
   5145  1.1  mrg       rtx reg, offset;
   5146  1.1  mrg       if (!split_mem_address (XEXP (base_mem, 0), &reg, &offset))
   5147  1.1  mrg 	gcc_unreachable ();
   5148  1.1  mrg       RTVEC_ELT (p, b) =
   5149  1.1  mrg 	gen_rtx_SET (reg, plus_constant (Pmode, reg, base_update));
   5150  1.1  mrg     }
   5151  1.1  mrg   return gen_rtx_PARALLEL (VOIDmode, p);
   5152  1.1  mrg }
   5153  1.1  mrg 
   5154  1.1  mrg /* CDX ldwm/stwm peephole optimization pattern related routines.  */
   5155  1.1  mrg 
   5156  1.1  mrg /* Data structure and sorting function for ldwm/stwm peephole optimizers.  */
   5157  1.1  mrg struct ldstwm_operand
   5158  1.1  mrg {
   5159  1.1  mrg   int offset;	/* Offset from base register.  */
   5160  1.1  mrg   rtx reg;	/* Register to store at this offset.  */
   5161  1.1  mrg   rtx mem;	/* Original mem.  */
   5162  1.1  mrg   bool bad;	/* True if this load/store can't be combined.  */
   5163  1.1  mrg   bool rewrite; /* True if we should rewrite using scratch.  */
   5164  1.1  mrg };
   5165  1.1  mrg 
   5166  1.1  mrg static int
   5167  1.1  mrg compare_ldstwm_operands (const void *arg1, const void *arg2)
   5168  1.1  mrg {
   5169  1.1  mrg   const struct ldstwm_operand *op1 = (const struct ldstwm_operand *) arg1;
   5170  1.1  mrg   const struct ldstwm_operand *op2 = (const struct ldstwm_operand *) arg2;
   5171  1.1  mrg   if (op1->bad)
   5172  1.1  mrg     return op2->bad ? 0 : 1;
   5173  1.1  mrg   else if (op2->bad)
   5174  1.1  mrg     return -1;
   5175  1.1  mrg   else
   5176  1.1  mrg     return op1->offset - op2->offset;
   5177  1.1  mrg }
   5178  1.1  mrg 
   5179  1.1  mrg /* Helper function: return true if a load/store using REGNO with address
   5180  1.1  mrg    BASEREG and offset OFFSET meets the constraints for a 2-byte CDX ldw.n,
   5181  1.1  mrg    stw.n, ldwsp.n, or stwsp.n instruction.  */
   5182  1.1  mrg static bool
   5183  1.1  mrg can_use_cdx_ldstw (int regno, int basereg, int offset)
   5184  1.1  mrg {
   5185  1.1  mrg   if (CDX_REG_P (regno) && CDX_REG_P (basereg)
   5186  1.1  mrg       && (offset & 0x3) == 0 && offset >= 0 && offset < 0x40)
   5187  1.1  mrg     return true;
   5188  1.1  mrg   else if (basereg == SP_REGNO
   5189  1.1  mrg 	   && offset >= 0 && offset < 0x80 && (offset & 0x3) == 0)
   5190  1.1  mrg     return true;
   5191  1.1  mrg   return false;
   5192  1.1  mrg }
   5193  1.1  mrg 
   5194  1.1  mrg /* This function is called from peephole2 optimizers to try to merge
   5195  1.1  mrg    a series of individual loads and stores into a ldwm or stwm.  It
   5196  1.1  mrg    can also rewrite addresses inside the individual loads and stores
   5197  1.1  mrg    using a common base register using a scratch register and smaller
   5198  1.1  mrg    offsets if that allows them to use CDX ldw.n or stw.n instructions
   5199  1.1  mrg    instead of 4-byte loads or stores.
   5200  1.1  mrg    N is the number of insns we are trying to merge.  SCRATCH is non-null
   5201  1.1  mrg    if there is a scratch register available.  The OPERANDS array contains
   5202  1.1  mrg    alternating REG (even) and MEM (odd) operands.  */
   5203  1.1  mrg bool
   5204  1.1  mrg gen_ldstwm_peep (bool load_p, int n, rtx scratch, rtx *operands)
   5205  1.1  mrg {
   5206  1.1  mrg   /* CDX ldwm/stwm instructions allow a maximum of 12 registers to be
   5207  1.1  mrg      specified.  */
   5208  1.1  mrg #define MAX_LDSTWM_OPS 12
   5209  1.1  mrg   struct ldstwm_operand sort[MAX_LDSTWM_OPS];
   5210  1.1  mrg   int basereg = -1;
   5211  1.1  mrg   int baseoffset;
   5212  1.1  mrg   int i, m, lastoffset, lastreg;
   5213  1.1  mrg   unsigned int regmask = 0, usemask = 0, regset;
   5214  1.1  mrg   bool needscratch;
   5215  1.1  mrg   int newbasereg;
   5216  1.1  mrg   int nbytes;
   5217  1.1  mrg 
   5218  1.1  mrg   if (!TARGET_HAS_CDX)
   5219  1.1  mrg     return false;
   5220  1.1  mrg   if (n < 2 || n > MAX_LDSTWM_OPS)
   5221  1.1  mrg     return false;
   5222  1.1  mrg 
   5223  1.1  mrg   /* Check all the operands for validity and initialize the sort array.
   5224  1.1  mrg      The places where we return false here are all situations that aren't
   5225  1.1  mrg      expected to ever happen -- invalid patterns, invalid registers, etc.  */
   5226  1.1  mrg   for (i = 0; i < n; i++)
   5227  1.1  mrg     {
   5228  1.1  mrg       rtx base, offset;
   5229  1.1  mrg       rtx reg = operands[i];
   5230  1.1  mrg       rtx mem = operands[i + n];
   5231  1.1  mrg       int r, o, regno;
   5232  1.1  mrg       bool bad = false;
   5233  1.1  mrg 
   5234  1.1  mrg       if (!REG_P (reg) || !MEM_P (mem))
   5235  1.1  mrg 	return false;
   5236  1.1  mrg 
   5237  1.1  mrg       regno = REGNO (reg);
   5238  1.1  mrg       if (regno > 31)
   5239  1.1  mrg 	return false;
   5240  1.1  mrg       if (load_p && (regmask & (1 << regno)) != 0)
   5241  1.1  mrg 	return false;
   5242  1.1  mrg       regmask |= 1 << regno;
   5243  1.1  mrg 
   5244  1.1  mrg       if (!split_mem_address (XEXP (mem, 0), &base, &offset))
   5245  1.1  mrg 	return false;
   5246  1.1  mrg       r = REGNO (base);
   5247  1.1  mrg       o = INTVAL (offset);
   5248  1.1  mrg 
   5249  1.1  mrg       if (basereg == -1)
   5250  1.1  mrg 	basereg = r;
   5251  1.1  mrg       else if (r != basereg)
   5252  1.1  mrg 	bad = true;
   5253  1.1  mrg       usemask |= 1 << r;
   5254  1.1  mrg 
   5255  1.1  mrg       sort[i].bad = bad;
   5256  1.1  mrg       sort[i].rewrite = false;
   5257  1.1  mrg       sort[i].offset = o;
   5258  1.1  mrg       sort[i].reg = reg;
   5259  1.1  mrg       sort[i].mem = mem;
   5260  1.1  mrg     }
   5261  1.1  mrg 
   5262  1.1  mrg   /* If we are doing a series of register loads, we can't safely reorder
   5263  1.1  mrg      them if any of the regs used in addr expressions are also being set.  */
   5264  1.1  mrg   if (load_p && (regmask & usemask))
   5265  1.1  mrg     return false;
   5266  1.1  mrg 
   5267  1.1  mrg   /* Sort the array by increasing mem offset order, then check that
   5268  1.1  mrg      offsets are valid and register order matches mem order.  At the
   5269  1.1  mrg      end of this loop, m is the number of loads/stores we will try to
   5270  1.1  mrg      combine; the rest are leftovers.  */
   5271  1.1  mrg   qsort (sort, n, sizeof (struct ldstwm_operand), compare_ldstwm_operands);
   5272  1.1  mrg 
   5273  1.1  mrg   baseoffset = sort[0].offset;
   5274  1.1  mrg   needscratch = baseoffset != 0;
   5275  1.1  mrg   if (needscratch && !scratch)
   5276  1.1  mrg     return false;
   5277  1.1  mrg 
   5278  1.1  mrg   lastreg = regmask = regset = 0;
   5279  1.1  mrg   lastoffset = baseoffset;
   5280  1.1  mrg   for (m = 0; m < n && !sort[m].bad; m++)
   5281  1.1  mrg     {
   5282  1.1  mrg       int thisreg = REGNO (sort[m].reg);
   5283  1.1  mrg       if (sort[m].offset != lastoffset
   5284  1.1  mrg 	  || (m > 0 && lastreg >= thisreg)
   5285  1.1  mrg 	  || !nios2_ldstwm_regset_p (thisreg, &regset))
   5286  1.1  mrg 	break;
   5287  1.1  mrg       lastoffset += 4;
   5288  1.1  mrg       lastreg = thisreg;
   5289  1.1  mrg       regmask |= (1 << thisreg);
   5290  1.1  mrg     }
   5291  1.1  mrg 
   5292  1.1  mrg   /* For loads, make sure we are not overwriting the scratch reg.
   5293  1.1  mrg      The peephole2 pattern isn't supposed to match unless the register is
   5294  1.1  mrg      unused all the way through, so this isn't supposed to happen anyway.  */
   5295  1.1  mrg   if (load_p
   5296  1.1  mrg       && needscratch
   5297  1.1  mrg       && ((1 << REGNO (scratch)) & regmask) != 0)
   5298  1.1  mrg     return false;
   5299  1.1  mrg   newbasereg = needscratch ? (int) REGNO (scratch) : basereg;
   5300  1.1  mrg 
   5301  1.1  mrg   /* We may be able to combine only the first m of the n total loads/stores
   5302  1.1  mrg      into a single instruction.  If m < 2, there's no point in emitting
   5303  1.1  mrg      a ldwm/stwm at all, but we might be able to do further optimizations
   5304  1.1  mrg      if we have a scratch.  We will count the instruction lengths of the
   5305  1.1  mrg      old and new patterns and store the savings in nbytes.  */
   5306  1.1  mrg   if (m < 2)
   5307  1.1  mrg     {
   5308  1.1  mrg       if (!needscratch)
   5309  1.1  mrg 	return false;
   5310  1.1  mrg       m = 0;
   5311  1.1  mrg       nbytes = 0;
   5312  1.1  mrg     }
   5313  1.1  mrg   else
   5314  1.1  mrg     nbytes = -4;  /* Size of ldwm/stwm.  */
   5315  1.1  mrg   if (needscratch)
   5316  1.1  mrg     {
   5317  1.1  mrg       int bo = baseoffset > 0 ? baseoffset : -baseoffset;
   5318  1.1  mrg       if (CDX_REG_P (newbasereg)
   5319  1.1  mrg 	  && CDX_REG_P (basereg)
   5320  1.1  mrg 	  && bo <= 128 && bo > 0 && (bo & (bo - 1)) == 0)
   5321  1.1  mrg 	nbytes -= 2;  /* Size of addi.n/subi.n.  */
   5322  1.1  mrg       else
   5323  1.1  mrg 	nbytes -= 4;  /* Size of non-CDX addi.  */
   5324  1.1  mrg     }
   5325  1.1  mrg 
   5326  1.1  mrg   /* Count the size of the input load/store instructions being replaced.  */
   5327  1.1  mrg   for (i = 0; i < m; i++)
   5328  1.1  mrg     if (can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset))
   5329  1.1  mrg       nbytes += 2;
   5330  1.1  mrg     else
   5331  1.1  mrg       nbytes += 4;
   5332  1.1  mrg 
   5333  1.1  mrg   /* We may also be able to save a bit if we can rewrite non-CDX
   5334  1.1  mrg      load/stores that can't be combined into the ldwm/stwm into CDX
   5335  1.1  mrg      load/stores using the scratch reg.  For example, this might happen
   5336  1.1  mrg      if baseoffset is large, by bringing in the offsets in the load/store
   5337  1.1  mrg      instructions within the range that fits in the CDX instruction.  */
   5338  1.1  mrg   if (needscratch && CDX_REG_P (newbasereg))
   5339  1.1  mrg     for (i = m; i < n && !sort[i].bad; i++)
   5340  1.1  mrg       if (!can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset)
   5341  1.1  mrg 	  && can_use_cdx_ldstw (REGNO (sort[i].reg), newbasereg,
   5342  1.1  mrg 				sort[i].offset - baseoffset))
   5343  1.1  mrg 	{
   5344  1.1  mrg 	  sort[i].rewrite = true;
   5345  1.1  mrg 	  nbytes += 2;
   5346  1.1  mrg 	}
   5347  1.1  mrg 
   5348  1.1  mrg   /* Are we good to go?  */
   5349  1.1  mrg   if (nbytes <= 0)
   5350  1.1  mrg     return false;
   5351  1.1  mrg 
   5352  1.1  mrg   /* Emit the scratch load.  */
   5353  1.1  mrg   if (needscratch)
   5354  1.1  mrg     emit_insn (gen_rtx_SET (scratch, XEXP (sort[0].mem, 0)));
   5355  1.1  mrg 
   5356  1.1  mrg   /* Emit the ldwm/stwm insn.  */
   5357  1.1  mrg   if (m > 0)
   5358  1.1  mrg     {
   5359  1.1  mrg       rtvec p = rtvec_alloc (m);
   5360  1.1  mrg       for (i = 0; i < m; i++)
   5361  1.1  mrg 	{
   5362  1.1  mrg 	  int offset = sort[i].offset;
   5363  1.1  mrg 	  rtx mem, reg = sort[i].reg;
   5364  1.1  mrg 	  rtx base_reg = gen_rtx_REG (Pmode, newbasereg);
   5365  1.1  mrg 	  if (needscratch)
   5366  1.1  mrg 	    offset -= baseoffset;
   5367  1.1  mrg 	  mem = gen_rtx_MEM (SImode, plus_constant (Pmode, base_reg, offset));
   5368  1.1  mrg 	  if (load_p)
   5369  1.1  mrg 	    RTVEC_ELT (p, i) = gen_rtx_SET (reg, mem);
   5370  1.1  mrg 	  else
   5371  1.1  mrg 	    RTVEC_ELT (p, i) = gen_rtx_SET (mem, reg);
   5372  1.1  mrg 	}
   5373  1.1  mrg       emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
   5374  1.1  mrg     }
   5375  1.1  mrg 
   5376  1.1  mrg   /* Emit any leftover load/stores as individual instructions, doing
   5377  1.1  mrg      the previously-noted rewrites to use the scratch reg.  */
   5378  1.1  mrg   for (i = m; i < n; i++)
   5379  1.1  mrg     {
   5380  1.1  mrg       rtx reg = sort[i].reg;
   5381  1.1  mrg       rtx mem = sort[i].mem;
   5382  1.1  mrg       if (sort[i].rewrite)
   5383  1.1  mrg 	{
   5384  1.1  mrg 	  int offset = sort[i].offset - baseoffset;
   5385  1.1  mrg 	  mem = gen_rtx_MEM (SImode, plus_constant (Pmode, scratch, offset));
   5386  1.1  mrg 	}
   5387  1.1  mrg       if (load_p)
   5388  1.1  mrg 	emit_move_insn (reg, mem);
   5389  1.1  mrg       else
   5390  1.1  mrg 	emit_move_insn (mem, reg);
   5391  1.1  mrg     }
   5392  1.1  mrg   return true;
   5393  1.1  mrg }
   5394  1.1  mrg 
   5395  1.1  mrg /* Implement TARGET_MACHINE_DEPENDENT_REORG:
   5396  1.1  mrg    We use this hook when emitting CDX code to enforce the 4-byte
   5397  1.1  mrg    alignment requirement for labels that are used as the targets of
   5398  1.1  mrg    jmpi instructions.  CDX code can otherwise contain a mix of 16-bit
   5399  1.1  mrg    and 32-bit instructions aligned on any 16-bit boundary, but functions
   5400  1.1  mrg    and jmpi labels have to be 32-bit aligned because of the way the address
   5401  1.1  mrg    is encoded in the instruction.  */
   5402  1.1  mrg 
   5403  1.1  mrg static unsigned char *label_align;
   5404  1.1  mrg static int min_labelno, max_labelno;
   5405  1.1  mrg 
   5406  1.1  mrg static void
   5407  1.1  mrg nios2_reorg (void)
   5408  1.1  mrg {
   5409  1.1  mrg   bool changed = true;
   5410  1.1  mrg   rtx_insn *insn;
   5411  1.1  mrg 
   5412  1.1  mrg   if (!TARGET_HAS_CDX)
   5413  1.1  mrg     return;
   5414  1.1  mrg 
   5415  1.1  mrg   /* Initialize the data structures.  */
   5416  1.1  mrg   if (label_align)
   5417  1.1  mrg     free (label_align);
   5418  1.1  mrg   max_labelno = max_label_num ();
   5419  1.1  mrg   min_labelno = get_first_label_num ();
   5420  1.1  mrg   label_align = XCNEWVEC (unsigned char, max_labelno - min_labelno + 1);
   5421  1.1  mrg 
   5422  1.1  mrg   /* Iterate on inserting alignment and adjusting branch lengths until
   5423  1.1  mrg      no more changes.  */
   5424  1.1  mrg   while (changed)
   5425  1.1  mrg     {
   5426  1.1  mrg       changed = false;
   5427  1.1  mrg       shorten_branches (get_insns ());
   5428  1.1  mrg 
   5429  1.1  mrg       for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
   5430  1.1  mrg 	if (JUMP_P (insn) && insn_variable_length_p (insn))
   5431  1.1  mrg 	  {
   5432  1.1  mrg 	    rtx label = JUMP_LABEL (insn);
   5433  1.1  mrg 	    /* We use the current fact that all cases of 'jmpi'
   5434  1.1  mrg 	       doing the actual branch in the machine description
   5435  1.1  mrg 	       has a computed length of 6 or 8.  Length 4 and below
   5436  1.1  mrg 	       are all PC-relative 'br' branches without the jump-align
   5437  1.1  mrg 	       problem.  */
   5438  1.1  mrg 	    if (label && LABEL_P (label) && get_attr_length (insn) > 4)
   5439  1.1  mrg 	      {
   5440  1.1  mrg 		int index = CODE_LABEL_NUMBER (label) - min_labelno;
   5441  1.1  mrg 		if (label_align[index] != 2)
   5442  1.1  mrg 		  {
   5443  1.1  mrg 		    label_align[index] = 2;
   5444  1.1  mrg 		    changed = true;
   5445  1.1  mrg 		  }
   5446  1.1  mrg 	      }
   5447  1.1  mrg 	  }
   5448  1.1  mrg     }
   5449  1.1  mrg }
   5450  1.1  mrg 
   5451  1.1  mrg /* Implement LABEL_ALIGN, using the information gathered in nios2_reorg.  */
   5452  1.1  mrg int
   5453  1.1  mrg nios2_label_align (rtx label)
   5454  1.1  mrg {
   5455  1.1  mrg   int n = CODE_LABEL_NUMBER (label);
   5456  1.1  mrg 
   5457  1.1  mrg   if (label_align && n >= min_labelno && n <= max_labelno)
   5458  1.1  mrg     return MAX (label_align[n - min_labelno], align_labels.levels[0].log);
   5459  1.1  mrg   return align_labels.levels[0].log;
   5460  1.1  mrg }
   5461  1.1  mrg 
   5462  1.1  mrg /* Implement ADJUST_REG_ALLOC_ORDER.  We use the default ordering
   5463  1.1  mrg    for R1 and non-CDX R2 code; for CDX we tweak thing to prefer
   5464  1.1  mrg    the registers that can be used as operands to instructions that
   5465  1.1  mrg    have 3-bit register fields.  */
   5466  1.1  mrg void
   5467  1.1  mrg nios2_adjust_reg_alloc_order (void)
   5468  1.1  mrg {
   5469  1.1  mrg   const int cdx_reg_alloc_order[] =
   5470  1.1  mrg     {
   5471  1.1  mrg       /* Call-clobbered GPRs within CDX 3-bit encoded range.  */
   5472  1.1  mrg       2, 3, 4, 5, 6, 7,
   5473  1.1  mrg       /* Call-saved GPRs within CDX 3-bit encoded range.  */
   5474  1.1  mrg       16, 17,
   5475  1.1  mrg       /* Other call-clobbered GPRs.  */
   5476  1.1  mrg       8, 9, 10, 11, 12, 13, 14, 15,
   5477  1.1  mrg       /* Other call-saved GPRs. RA placed first since it is always saved.  */
   5478  1.1  mrg       31, 18, 19, 20, 21, 22, 23, 28,
   5479  1.1  mrg       /* Fixed GPRs, not used by the register allocator.  */
   5480  1.1  mrg       0, 1, 24, 25, 26, 27, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39
   5481  1.1  mrg    };
   5482  1.1  mrg 
   5483  1.1  mrg   if (TARGET_HAS_CDX)
   5484  1.1  mrg     memcpy (reg_alloc_order, cdx_reg_alloc_order,
   5485  1.1  mrg 	    sizeof (int) * FIRST_PSEUDO_REGISTER);
   5486  1.1  mrg }
   5487  1.1  mrg 
   5488  1.1  mrg 
   5489  1.1  mrg /* Initialize the GCC target structure.  */
   5491  1.1  mrg #undef TARGET_ASM_FUNCTION_PROLOGUE
   5492  1.1  mrg #define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
   5493  1.1  mrg 
   5494  1.1  mrg #undef TARGET_IN_SMALL_DATA_P
   5495  1.1  mrg #define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
   5496  1.1  mrg 
   5497  1.1  mrg #undef  TARGET_SECTION_TYPE_FLAGS
   5498  1.1  mrg #define TARGET_SECTION_TYPE_FLAGS  nios2_section_type_flags
   5499  1.1  mrg 
   5500  1.1  mrg #undef TARGET_INIT_BUILTINS
   5501  1.1  mrg #define TARGET_INIT_BUILTINS nios2_init_builtins
   5502  1.1  mrg #undef TARGET_EXPAND_BUILTIN
   5503  1.1  mrg #define TARGET_EXPAND_BUILTIN nios2_expand_builtin
   5504  1.1  mrg #undef TARGET_BUILTIN_DECL
   5505  1.1  mrg #define TARGET_BUILTIN_DECL nios2_builtin_decl
   5506  1.1  mrg 
   5507  1.1  mrg #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   5508  1.1  mrg #define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
   5509  1.1  mrg 
   5510  1.1  mrg #undef TARGET_CAN_ELIMINATE
   5511  1.1  mrg #define TARGET_CAN_ELIMINATE nios2_can_eliminate
   5512  1.1  mrg 
   5513  1.1  mrg #undef TARGET_FUNCTION_ARG
   5514  1.1  mrg #define TARGET_FUNCTION_ARG nios2_function_arg
   5515  1.1  mrg 
   5516  1.1  mrg #undef TARGET_FUNCTION_ARG_ADVANCE
   5517  1.1  mrg #define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
   5518  1.1  mrg 
   5519  1.1  mrg #undef TARGET_FUNCTION_ARG_PADDING
   5520  1.1  mrg #define TARGET_FUNCTION_ARG_PADDING nios2_function_arg_padding
   5521  1.1  mrg 
   5522  1.1  mrg #undef TARGET_ARG_PARTIAL_BYTES
   5523  1.1  mrg #define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
   5524  1.1  mrg 
   5525  1.1  mrg #undef TARGET_TRAMPOLINE_INIT
   5526  1.1  mrg #define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
   5527  1.1  mrg 
   5528  1.1  mrg #undef TARGET_FUNCTION_VALUE
   5529  1.1  mrg #define TARGET_FUNCTION_VALUE nios2_function_value
   5530  1.1  mrg 
   5531  1.1  mrg #undef TARGET_LIBCALL_VALUE
   5532  1.1  mrg #define TARGET_LIBCALL_VALUE nios2_libcall_value
   5533  1.1  mrg 
   5534  1.1  mrg #undef TARGET_FUNCTION_VALUE_REGNO_P
   5535  1.1  mrg #define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
   5536  1.1  mrg 
   5537  1.1  mrg #undef TARGET_RETURN_IN_MEMORY
   5538  1.1  mrg #define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
   5539  1.1  mrg 
   5540  1.1  mrg #undef TARGET_PROMOTE_PROTOTYPES
   5541  1.1  mrg #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
   5542  1.1  mrg 
   5543  1.1  mrg #undef TARGET_SETUP_INCOMING_VARARGS
   5544  1.1  mrg #define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
   5545  1.1  mrg 
   5546  1.1  mrg #undef TARGET_MUST_PASS_IN_STACK
   5547  1.1  mrg #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
   5548  1.1  mrg 
   5549  1.1  mrg #undef TARGET_LEGITIMATE_CONSTANT_P
   5550  1.1  mrg #define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
   5551  1.1  mrg 
   5552  1.1  mrg #undef TARGET_LEGITIMIZE_ADDRESS
   5553  1.1  mrg #define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
   5554  1.1  mrg 
   5555  1.1  mrg #undef TARGET_DELEGITIMIZE_ADDRESS
   5556  1.1  mrg #define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address
   5557  1.1  mrg 
   5558  1.1  mrg #undef TARGET_LEGITIMATE_ADDRESS_P
   5559  1.1  mrg #define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
   5560  1.1  mrg 
   5561  1.1  mrg #undef TARGET_PREFERRED_RELOAD_CLASS
   5562  1.1  mrg #define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
   5563  1.1  mrg 
   5564  1.1  mrg #undef TARGET_RTX_COSTS
   5565  1.1  mrg #define TARGET_RTX_COSTS nios2_rtx_costs
   5566  1.1  mrg 
   5567  1.1  mrg #undef TARGET_ADDRESS_COST
   5568  1.1  mrg #define TARGET_ADDRESS_COST nios2_address_cost
   5569  1.1  mrg 
   5570  1.1  mrg #undef TARGET_HAVE_TLS
   5571  1.1  mrg #define TARGET_HAVE_TLS TARGET_LINUX_ABI
   5572  1.1  mrg 
   5573  1.1  mrg #undef TARGET_CANNOT_FORCE_CONST_MEM
   5574  1.1  mrg #define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
   5575  1.1  mrg 
   5576  1.1  mrg #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
   5577  1.1  mrg #define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
   5578  1.1  mrg 
   5579  1.1  mrg #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
   5580  1.1  mrg #define TARGET_PRINT_OPERAND_PUNCT_VALID_P nios2_print_operand_punct_valid_p
   5581  1.1  mrg 
   5582  1.1  mrg #undef TARGET_PRINT_OPERAND
   5583  1.1  mrg #define TARGET_PRINT_OPERAND nios2_print_operand
   5584  1.1  mrg 
   5585  1.1  mrg #undef TARGET_PRINT_OPERAND_ADDRESS
   5586  1.1  mrg #define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
   5587  1.1  mrg 
   5588  1.1  mrg #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
   5589  1.1  mrg #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra
   5590  1.1  mrg 
   5591  1.1  mrg #undef TARGET_ASM_FILE_END
   5592  1.1  mrg #define TARGET_ASM_FILE_END nios2_asm_file_end
   5593  1.1  mrg 
   5594  1.1  mrg #undef TARGET_OPTION_OVERRIDE
   5595  1.1  mrg #define TARGET_OPTION_OVERRIDE nios2_option_override
   5596  1.1  mrg 
   5597  1.1  mrg #undef TARGET_OPTION_SAVE
   5598  1.1  mrg #define TARGET_OPTION_SAVE nios2_option_save
   5599  1.1  mrg 
   5600  1.1  mrg #undef TARGET_OPTION_RESTORE
   5601  1.1  mrg #define TARGET_OPTION_RESTORE nios2_option_restore
   5602  1.1  mrg 
   5603  1.1  mrg #undef TARGET_CAN_INLINE_P
   5604  1.1  mrg #define TARGET_CAN_INLINE_P nios2_can_inline_p
   5605  1.1  mrg 
   5606  1.1  mrg #undef TARGET_SET_CURRENT_FUNCTION
   5607  1.1  mrg #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
   5608  1.1  mrg 
   5609  1.1  mrg #undef TARGET_OPTION_VALID_ATTRIBUTE_P
   5610  1.1  mrg #define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
   5611  1.1  mrg 
   5612  1.1  mrg #undef TARGET_OPTION_PRAGMA_PARSE
   5613  1.1  mrg #define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
   5614  1.1  mrg 
   5615  1.1  mrg #undef TARGET_MERGE_DECL_ATTRIBUTES
   5616  1.1  mrg #define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
   5617  1.1  mrg 
   5618  1.1  mrg #undef  TARGET_ASM_CAN_OUTPUT_MI_THUNK
   5619  1.1  mrg #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
   5620  1.1  mrg   hook_bool_const_tree_hwi_hwi_const_tree_true
   5621  1.1  mrg 
   5622  1.1  mrg #undef  TARGET_ASM_OUTPUT_MI_THUNK
   5623  1.1  mrg #define TARGET_ASM_OUTPUT_MI_THUNK nios2_asm_output_mi_thunk
   5624  1.1  mrg 
   5625           #undef TARGET_MACHINE_DEPENDENT_REORG
   5626           #define TARGET_MACHINE_DEPENDENT_REORG nios2_reorg
   5627           
   5628           #undef TARGET_CONSTANT_ALIGNMENT
   5629           #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
   5630           
   5631           #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
   5632           #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
   5633           
   5634           struct gcc_target targetm = TARGET_INITIALIZER;
   5635           
   5636           #include "gt-nios2.h"
   5637