Home | History | Annotate | Line # | Download | only in tilepro
      1  1.1  mrg /* Subroutines used for code generation on the Tilera TILEPro.
      2  1.1  mrg    Copyright (C) 2011-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Walter Lee (walt (at) tilera.com)
      4  1.1  mrg 
      5  1.1  mrg    This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg    GCC is free software; you can redistribute it and/or modify it
      8  1.1  mrg    under the terms of the GNU General Public License as published
      9  1.1  mrg    by the Free Software Foundation; either version 3, or (at your
     10  1.1  mrg    option) any later version.
     11  1.1  mrg 
     12  1.1  mrg    GCC is distributed in the hope that it will be useful, but WITHOUT
     13  1.1  mrg    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14  1.1  mrg    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15  1.1  mrg    License for more details.
     16  1.1  mrg 
     17  1.1  mrg    You should have received a copy of the GNU General Public License
     18  1.1  mrg    along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #define IN_TARGET_CODE 1
     22  1.1  mrg 
     23  1.1  mrg #include "config.h"
     24  1.1  mrg #include "system.h"
     25  1.1  mrg #include "coretypes.h"
     26  1.1  mrg #include "backend.h"
     27  1.1  mrg #include "target.h"
     28  1.1  mrg #include "rtl.h"
     29  1.1  mrg #include "tree.h"
     30  1.1  mrg #include "gimple.h"
     31  1.1  mrg #include "df.h"
     32  1.1  mrg #include "memmodel.h"
     33  1.1  mrg #include "tm_p.h"
     34  1.1  mrg #include "stringpool.h"
     35  1.1  mrg #include "attribs.h"
     36  1.1  mrg #include "expmed.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.h"
     42  1.1  mrg #include "output.h"
     43  1.1  mrg #include "insn-attr.h"
     44  1.1  mrg #include "alias.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 "langhooks.h"
     50  1.1  mrg #include "cfgrtl.h"
     51  1.1  mrg #include "tm-constrs.h"
     52  1.1  mrg #include "dwarf2.h"
     53  1.1  mrg #include "fold-const.h"
     54  1.1  mrg #include "stor-layout.h"
     55  1.1  mrg #include "gimplify.h"
     56  1.1  mrg #include "tilepro-builtins.h"
     57  1.1  mrg #include "tilepro-multiply.h"
     58  1.1  mrg #include "builtins.h"
     59  1.1  mrg 
     60  1.1  mrg /* This file should be included last.  */
     61  1.1  mrg #include "target-def.h"
     62  1.1  mrg 
     63  1.1  mrg /* SYMBOL_REF for GOT */
     64  1.1  mrg static GTY(()) rtx g_got_symbol = NULL;
     65  1.1  mrg 
     66  1.1  mrg /* Report whether we're printing out the first address fragment of a
     67  1.1  mrg    POST_INC or POST_DEC memory reference, from TARGET_PRINT_OPERAND to
     68  1.1  mrg    TARGET_PRINT_OPERAND_ADDRESS.  */
     69  1.1  mrg static bool output_memory_autoinc_first;
     70  1.1  mrg 
     71  1.1  mrg 
     72  1.1  mrg 
     74  1.1  mrg /* Option handling  */
     75  1.1  mrg 
     76  1.1  mrg /* Implement TARGET_OPTION_OVERRIDE.  */
     77  1.1  mrg static void
     78  1.1  mrg tilepro_option_override (void)
     79  1.1  mrg {
     80  1.1  mrg   /* When modulo scheduling is enabled, we still rely on regular
     81  1.1  mrg      scheduler for bundling.  */
     82  1.1  mrg   if (flag_modulo_sched)
     83  1.1  mrg     flag_resched_modulo_sched = 1;
     84  1.1  mrg }
     85  1.1  mrg 
     86  1.1  mrg 
     88  1.1  mrg 
     89  1.1  mrg /* Implement TARGET_SCALAR_MODE_SUPPORTED_P.  */
     90  1.1  mrg static bool
     91  1.1  mrg tilepro_scalar_mode_supported_p (scalar_mode mode)
     92  1.1  mrg {
     93  1.1  mrg   switch (mode)
     94  1.1  mrg     {
     95  1.1  mrg     case E_QImode:
     96  1.1  mrg     case E_HImode:
     97  1.1  mrg     case E_SImode:
     98  1.1  mrg     case E_DImode:
     99  1.1  mrg       return true;
    100  1.1  mrg 
    101  1.1  mrg     case E_SFmode:
    102  1.1  mrg     case E_DFmode:
    103  1.1  mrg       return true;
    104  1.1  mrg 
    105  1.1  mrg     default:
    106  1.1  mrg       return false;
    107  1.1  mrg     }
    108  1.1  mrg }
    109  1.1  mrg 
    110  1.1  mrg 
    111  1.1  mrg /* Implement TARGET_VECTOR_MODE_SUPPORTED_P.  */
    112  1.1  mrg static bool
    113  1.1  mrg tile_vector_mode_supported_p (machine_mode mode)
    114  1.1  mrg {
    115  1.1  mrg   return mode == V4QImode || mode == V2HImode;
    116  1.1  mrg }
    117  1.1  mrg 
    118  1.1  mrg 
    119  1.1  mrg /* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
    120  1.1  mrg static bool
    121  1.1  mrg tilepro_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED,
    122  1.1  mrg 				rtx x ATTRIBUTE_UNUSED)
    123  1.1  mrg {
    124  1.1  mrg   return true;
    125  1.1  mrg }
    126  1.1  mrg 
    127  1.1  mrg 
    128  1.1  mrg /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL.  */
    129  1.1  mrg static bool
    130  1.1  mrg tilepro_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
    131  1.1  mrg {
    132  1.1  mrg   return decl != NULL;
    133  1.1  mrg }
    134  1.1  mrg 
    135  1.1  mrg 
    136  1.1  mrg /* Implement TARGET_PASS_BY_REFERENCE.  Variable sized types are
    137  1.1  mrg    passed by reference.  */
    138  1.1  mrg static bool
    139  1.1  mrg tilepro_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
    140  1.1  mrg {
    141  1.1  mrg   return (arg.type
    142  1.1  mrg 	  && TYPE_SIZE (arg.type)
    143  1.1  mrg 	  && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST);
    144  1.1  mrg }
    145  1.1  mrg 
    146  1.1  mrg 
    147  1.1  mrg /* Implement TARGET_RETURN_IN_MEMORY.  */
    148  1.1  mrg static bool
    149  1.1  mrg tilepro_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
    150  1.1  mrg {
    151  1.1  mrg   return !IN_RANGE (int_size_in_bytes (type),
    152  1.1  mrg 		    0, TILEPRO_NUM_RETURN_REGS * UNITS_PER_WORD);
    153  1.1  mrg }
    154  1.1  mrg 
    155  1.1  mrg 
    156  1.1  mrg /* Implement TARGET_FUNCTION_ARG_BOUNDARY.  */
    157  1.1  mrg static unsigned int
    158  1.1  mrg tilepro_function_arg_boundary (machine_mode mode, const_tree type)
    159  1.1  mrg {
    160  1.1  mrg   unsigned int alignment;
    161  1.1  mrg 
    162  1.1  mrg   alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
    163  1.1  mrg   if (alignment < PARM_BOUNDARY)
    164  1.1  mrg     alignment = PARM_BOUNDARY;
    165  1.1  mrg   if (alignment > STACK_BOUNDARY)
    166  1.1  mrg     alignment = STACK_BOUNDARY;
    167  1.1  mrg   return alignment;
    168  1.1  mrg }
    169  1.1  mrg 
    170  1.1  mrg 
    171  1.1  mrg /* Implement TARGET_FUNCTION_ARG.  */
    172  1.1  mrg static rtx
    173  1.1  mrg tilepro_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
    174  1.1  mrg {
    175  1.1  mrg   CUMULATIVE_ARGS cum = *get_cumulative_args (cum_v);
    176  1.1  mrg   int byte_size = arg.promoted_size_in_bytes ();
    177  1.1  mrg   bool doubleword_aligned_p;
    178  1.1  mrg 
    179  1.1  mrg   if (cum >= TILEPRO_NUM_ARG_REGS)
    180  1.1  mrg     return NULL_RTX;
    181  1.1  mrg 
    182  1.1  mrg   /* See whether the argument has doubleword alignment.  */
    183  1.1  mrg   doubleword_aligned_p =
    184  1.1  mrg     tilepro_function_arg_boundary (arg.mode, arg.type) > BITS_PER_WORD;
    185  1.1  mrg 
    186  1.1  mrg   if (doubleword_aligned_p)
    187  1.1  mrg     cum += cum & 1;
    188  1.1  mrg 
    189  1.1  mrg   /* The ABI does not allow parameters to be passed partially in reg
    190  1.1  mrg      and partially in stack.  */
    191  1.1  mrg   if ((cum + (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
    192  1.1  mrg       > TILEPRO_NUM_ARG_REGS)
    193  1.1  mrg     return NULL_RTX;
    194  1.1  mrg 
    195  1.1  mrg   return gen_rtx_REG (arg.mode, cum);
    196  1.1  mrg }
    197  1.1  mrg 
    198  1.1  mrg 
    199  1.1  mrg /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
    200  1.1  mrg static void
    201  1.1  mrg tilepro_function_arg_advance (cumulative_args_t cum_v,
    202  1.1  mrg 			      const function_arg_info &arg)
    203  1.1  mrg {
    204  1.1  mrg   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    205  1.1  mrg 
    206  1.1  mrg   int byte_size = arg.promoted_size_in_bytes ();
    207  1.1  mrg   int word_size = (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
    208  1.1  mrg   bool doubleword_aligned_p;
    209  1.1  mrg 
    210  1.1  mrg   /* See whether the argument has doubleword alignment.  */
    211  1.1  mrg   doubleword_aligned_p =
    212  1.1  mrg     tilepro_function_arg_boundary (arg.mode, arg.type) > BITS_PER_WORD;
    213  1.1  mrg 
    214  1.1  mrg   if (doubleword_aligned_p)
    215  1.1  mrg     *cum += *cum & 1;
    216  1.1  mrg 
    217  1.1  mrg   /* If the current argument does not fit in the pretend_args space,
    218  1.1  mrg      skip over it.  */
    219  1.1  mrg   if (*cum < TILEPRO_NUM_ARG_REGS
    220  1.1  mrg       && *cum + word_size > TILEPRO_NUM_ARG_REGS)
    221  1.1  mrg     *cum = TILEPRO_NUM_ARG_REGS;
    222  1.1  mrg 
    223  1.1  mrg   *cum += word_size;
    224  1.1  mrg }
    225  1.1  mrg 
    226  1.1  mrg 
    227  1.1  mrg /* Implement TARGET_FUNCTION_VALUE.  */
    228  1.1  mrg static rtx
    229  1.1  mrg tilepro_function_value (const_tree valtype, const_tree fn_decl_or_type,
    230  1.1  mrg 			bool outgoing ATTRIBUTE_UNUSED)
    231  1.1  mrg {
    232  1.1  mrg   machine_mode mode;
    233  1.1  mrg   int unsigned_p;
    234  1.1  mrg 
    235  1.1  mrg   mode = TYPE_MODE (valtype);
    236  1.1  mrg   unsigned_p = TYPE_UNSIGNED (valtype);
    237  1.1  mrg 
    238  1.1  mrg   mode = promote_function_mode (valtype, mode, &unsigned_p,
    239  1.1  mrg 				fn_decl_or_type, 1);
    240  1.1  mrg 
    241  1.1  mrg   return gen_rtx_REG (mode, 0);
    242  1.1  mrg }
    243  1.1  mrg 
    244  1.1  mrg 
    245  1.1  mrg /* Implement TARGET_LIBCALL_VALUE.  */
    246  1.1  mrg static rtx
    247  1.1  mrg tilepro_libcall_value (machine_mode mode,
    248  1.1  mrg 		       const_rtx fun ATTRIBUTE_UNUSED)
    249  1.1  mrg {
    250  1.1  mrg   return gen_rtx_REG (mode, 0);
    251  1.1  mrg }
    252  1.1  mrg 
    253  1.1  mrg 
    254  1.1  mrg /* Implement FUNCTION_VALUE_REGNO_P.  */
    255  1.1  mrg static bool
    256  1.1  mrg tilepro_function_value_regno_p (const unsigned int regno)
    257  1.1  mrg {
    258  1.1  mrg   return regno < TILEPRO_NUM_RETURN_REGS;
    259  1.1  mrg }
    260  1.1  mrg 
    261  1.1  mrg 
    262  1.1  mrg /* Implement TARGET_BUILD_BUILTIN_VA_LIST.  */
    263  1.1  mrg static tree
    264  1.1  mrg tilepro_build_builtin_va_list (void)
    265  1.1  mrg {
    266  1.1  mrg   tree f_args, f_skip, record, type_decl;
    267  1.1  mrg   bool owp;
    268  1.1  mrg 
    269  1.1  mrg   record = lang_hooks.types.make_type (RECORD_TYPE);
    270  1.1  mrg 
    271  1.1  mrg   type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
    272  1.1  mrg 			  get_identifier ("__va_list_tag"), record);
    273  1.1  mrg 
    274  1.1  mrg   f_args = build_decl (BUILTINS_LOCATION, FIELD_DECL,
    275  1.1  mrg 		       get_identifier ("__args"), ptr_type_node);
    276  1.1  mrg   f_skip = build_decl (BUILTINS_LOCATION, FIELD_DECL,
    277  1.1  mrg 		       get_identifier ("__skip"), ptr_type_node);
    278  1.1  mrg 
    279  1.1  mrg   DECL_FIELD_CONTEXT (f_args) = record;
    280  1.1  mrg 
    281  1.1  mrg   DECL_FIELD_CONTEXT (f_skip) = record;
    282  1.1  mrg 
    283  1.1  mrg   TREE_CHAIN (record) = type_decl;
    284  1.1  mrg   TYPE_NAME (record) = type_decl;
    285  1.1  mrg   TYPE_FIELDS (record) = f_args;
    286  1.1  mrg   TREE_CHAIN (f_args) = f_skip;
    287  1.1  mrg 
    288  1.1  mrg   /* We know this is being padded and we want it too.  It is an
    289  1.1  mrg      internal type so hide the warnings from the user.  */
    290  1.1  mrg   owp = warn_padded;
    291  1.1  mrg   warn_padded = false;
    292  1.1  mrg 
    293  1.1  mrg   layout_type (record);
    294  1.1  mrg 
    295  1.1  mrg   warn_padded = owp;
    296  1.1  mrg 
    297  1.1  mrg   /* The correct type is an array type of one element.  */
    298  1.1  mrg   return record;
    299  1.1  mrg }
    300  1.1  mrg 
    301  1.1  mrg 
    302  1.1  mrg /* Implement TARGET_EXPAND_BUILTIN_VA_START.  */
    303  1.1  mrg static void
    304  1.1  mrg tilepro_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
    305  1.1  mrg {
    306  1.1  mrg   tree f_args, f_skip;
    307  1.1  mrg   tree args, skip, t;
    308  1.1  mrg 
    309  1.1  mrg   f_args = TYPE_FIELDS (TREE_TYPE (valist));
    310  1.1  mrg   f_skip = TREE_CHAIN (f_args);
    311  1.1  mrg 
    312  1.1  mrg   args =
    313  1.1  mrg     build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE);
    314  1.1  mrg   skip =
    315  1.1  mrg     build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE);
    316  1.1  mrg 
    317  1.1  mrg   /* Find the __args area.  */
    318  1.1  mrg   t = make_tree (TREE_TYPE (args), virtual_incoming_args_rtx);
    319  1.1  mrg   t = fold_build_pointer_plus_hwi (t,
    320  1.1  mrg 				   UNITS_PER_WORD *
    321  1.1  mrg 				   (crtl->args.info - TILEPRO_NUM_ARG_REGS));
    322  1.1  mrg 
    323  1.1  mrg   if (crtl->args.pretend_args_size > 0)
    324  1.1  mrg     t = fold_build_pointer_plus_hwi (t, -STACK_POINTER_OFFSET);
    325  1.1  mrg 
    326  1.1  mrg   t = build2 (MODIFY_EXPR, TREE_TYPE (args), args, t);
    327  1.1  mrg   TREE_SIDE_EFFECTS (t) = 1;
    328  1.1  mrg   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    329  1.1  mrg 
    330  1.1  mrg   /* Find the __skip area.  */
    331  1.1  mrg   t = make_tree (TREE_TYPE (skip), virtual_incoming_args_rtx);
    332  1.1  mrg   t = fold_build_pointer_plus_hwi (t, -STACK_POINTER_OFFSET);
    333  1.1  mrg   t = build2 (MODIFY_EXPR, TREE_TYPE (skip), skip, t);
    334  1.1  mrg   TREE_SIDE_EFFECTS (t) = 1;
    335  1.1  mrg   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    336  1.1  mrg }
    337  1.1  mrg 
    338  1.1  mrg 
    339  1.1  mrg /* Implement TARGET_SETUP_INCOMING_VARARGS.  */
    340  1.1  mrg static void
    341  1.1  mrg tilepro_setup_incoming_varargs (cumulative_args_t cum,
    342  1.1  mrg 				const function_arg_info &arg,
    343  1.1  mrg 				int *pretend_args, int no_rtl)
    344  1.1  mrg {
    345  1.1  mrg   CUMULATIVE_ARGS local_cum = *get_cumulative_args (cum);
    346  1.1  mrg   int first_reg;
    347  1.1  mrg 
    348  1.1  mrg   /* The caller has advanced CUM up to, but not beyond, the last named
    349  1.1  mrg      argument.  Advance a local copy of CUM past the last "real" named
    350  1.1  mrg      argument, to find out how many registers are left over.  */
    351  1.1  mrg   targetm.calls.function_arg_advance (pack_cumulative_args (&local_cum), arg);
    352  1.1  mrg   first_reg = local_cum;
    353  1.1  mrg 
    354  1.1  mrg   if (local_cum < TILEPRO_NUM_ARG_REGS)
    355  1.1  mrg     {
    356  1.1  mrg       *pretend_args = UNITS_PER_WORD * (TILEPRO_NUM_ARG_REGS - first_reg);
    357  1.1  mrg 
    358  1.1  mrg       if (!no_rtl)
    359  1.1  mrg 	{
    360  1.1  mrg 	  alias_set_type set = get_varargs_alias_set ();
    361  1.1  mrg 	  rtx tmp =
    362  1.1  mrg 	    gen_rtx_MEM (BLKmode, plus_constant (Pmode, \
    363  1.1  mrg 						 virtual_incoming_args_rtx,
    364  1.1  mrg 						 -STACK_POINTER_OFFSET -
    365  1.1  mrg 						 UNITS_PER_WORD *
    366  1.1  mrg 						 (TILEPRO_NUM_ARG_REGS -
    367  1.1  mrg 						  first_reg)));
    368  1.1  mrg 	  MEM_NOTRAP_P (tmp) = 1;
    369  1.1  mrg 	  set_mem_alias_set (tmp, set);
    370  1.1  mrg 	  move_block_from_reg (first_reg, tmp,
    371  1.1  mrg 			       TILEPRO_NUM_ARG_REGS - first_reg);
    372  1.1  mrg 	}
    373  1.1  mrg     }
    374  1.1  mrg   else
    375  1.1  mrg     *pretend_args = 0;
    376  1.1  mrg }
    377  1.1  mrg 
    378  1.1  mrg 
    379  1.1  mrg /* Implement TARGET_GIMPLIFY_VA_ARG_EXPR.  Gimplify va_arg by updating
    380  1.1  mrg    the va_list structure VALIST as required to retrieve an argument of
    381  1.1  mrg    type TYPE, and returning that argument.
    382  1.1  mrg 
    383  1.1  mrg    ret = va_arg(VALIST, TYPE);
    384  1.1  mrg 
    385  1.1  mrg    generates code equivalent to:
    386  1.1  mrg 
    387  1.1  mrg     paddedsize = (sizeof(TYPE) + 3) & -4;
    388  1.1  mrg     if ((VALIST.__args + paddedsize > VALIST.__skip)
    389  1.1  mrg 	& (VALIST.__args <= VALIST.__skip))
    390  1.1  mrg       addr = VALIST.__skip + STACK_POINTER_OFFSET;
    391  1.1  mrg     else
    392  1.1  mrg       addr = VALIST.__args;
    393  1.1  mrg     VALIST.__args = addr + paddedsize;
    394  1.1  mrg     ret = *(TYPE *)addr;                                          */
    395  1.1  mrg static tree
    396  1.1  mrg tilepro_gimplify_va_arg_expr (tree valist, tree type, gimple_seq * pre_p,
    397  1.1  mrg 			      gimple_seq * post_p ATTRIBUTE_UNUSED)
    398  1.1  mrg {
    399  1.1  mrg   tree f_args, f_skip;
    400  1.1  mrg   tree args, skip;
    401  1.1  mrg   HOST_WIDE_INT size, rsize;
    402  1.1  mrg   tree addr, tmp;
    403  1.1  mrg   bool pass_by_reference_p;
    404  1.1  mrg 
    405  1.1  mrg   f_args = TYPE_FIELDS (va_list_type_node);
    406  1.1  mrg   f_skip = TREE_CHAIN (f_args);
    407  1.1  mrg 
    408  1.1  mrg   args =
    409  1.1  mrg     build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE);
    410  1.1  mrg   skip =
    411  1.1  mrg     build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE);
    412  1.1  mrg 
    413  1.1  mrg   addr = create_tmp_var (ptr_type_node, "va_arg");
    414  1.1  mrg 
    415  1.1  mrg   /* if an object is dynamically sized, a pointer to it is passed
    416  1.1  mrg      instead of the object itself.  */
    417  1.1  mrg   pass_by_reference_p = pass_va_arg_by_reference (type);
    418  1.1  mrg 
    419  1.1  mrg   if (pass_by_reference_p)
    420  1.1  mrg     type = build_pointer_type (type);
    421  1.1  mrg 
    422  1.1  mrg   size = int_size_in_bytes (type);
    423  1.1  mrg   rsize = ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD) * UNITS_PER_WORD;
    424  1.1  mrg 
    425  1.1  mrg   /* If the alignment of the type is greater than the default for a
    426  1.1  mrg      parameter, align to STACK_BOUNDARY.  */
    427  1.1  mrg   if (TYPE_ALIGN (type) > PARM_BOUNDARY)
    428  1.1  mrg     {
    429  1.1  mrg       /* Assert the only case we generate code for: when
    430  1.1  mrg          stack boundary = 2 * parm boundary.  */
    431  1.1  mrg       gcc_assert (STACK_BOUNDARY == PARM_BOUNDARY * 2);
    432  1.1  mrg 
    433  1.1  mrg       tmp = build2 (BIT_AND_EXPR, sizetype,
    434  1.1  mrg 		    fold_convert (sizetype, unshare_expr (args)),
    435  1.1  mrg 		    size_int (PARM_BOUNDARY / 8));
    436  1.1  mrg       tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node,
    437  1.1  mrg 		    unshare_expr (args), tmp);
    438  1.1  mrg 
    439  1.1  mrg       gimplify_assign (unshare_expr (args), tmp, pre_p);
    440  1.1  mrg     }
    441  1.1  mrg 
    442  1.1  mrg   /* Build conditional expression to calculate addr. The expression
    443  1.1  mrg      will be gimplified later.  */
    444  1.1  mrg   tmp = fold_build_pointer_plus_hwi (unshare_expr (args), rsize);
    445  1.1  mrg   tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
    446  1.1  mrg 		build2 (GT_EXPR, boolean_type_node, tmp, unshare_expr (skip)),
    447  1.1  mrg 		build2 (LE_EXPR, boolean_type_node, unshare_expr (args),
    448  1.1  mrg 			unshare_expr (skip)));
    449  1.1  mrg 
    450  1.1  mrg   tmp = build3 (COND_EXPR, ptr_type_node, tmp,
    451  1.1  mrg 		build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (skip),
    452  1.1  mrg 			size_int (STACK_POINTER_OFFSET)),
    453  1.1  mrg 		unshare_expr (args));
    454  1.1  mrg 
    455  1.1  mrg   gimplify_assign (addr, tmp, pre_p);
    456  1.1  mrg 
    457  1.1  mrg   /* Update VALIST.__args.  */
    458  1.1  mrg   tmp = fold_build_pointer_plus_hwi (addr, rsize);
    459  1.1  mrg   gimplify_assign (unshare_expr (args), tmp, pre_p);
    460  1.1  mrg 
    461  1.1  mrg   addr = fold_convert (build_pointer_type (type), addr);
    462  1.1  mrg 
    463  1.1  mrg   if (pass_by_reference_p)
    464  1.1  mrg     addr = build_va_arg_indirect_ref (addr);
    465  1.1  mrg 
    466  1.1  mrg   return build_va_arg_indirect_ref (addr);
    467  1.1  mrg }
    468  1.1  mrg 
    469  1.1  mrg 
    471  1.1  mrg 
    472  1.1  mrg /* Implement TARGET_RTX_COSTS.  */
    473  1.1  mrg static bool
    474  1.1  mrg tilepro_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
    475  1.1  mrg 		   int *total, bool speed)
    476  1.1  mrg {
    477  1.1  mrg   int code = GET_CODE (x);
    478  1.1  mrg 
    479  1.1  mrg   switch (code)
    480  1.1  mrg     {
    481  1.1  mrg     case CONST_INT:
    482  1.1  mrg       /* If this is an 8-bit constant, return zero since it can be
    483  1.1  mrg          used nearly anywhere with no cost.  If it is a valid operand
    484  1.1  mrg          for an ADD or AND, likewise return 0 if we know it will be
    485  1.1  mrg          used in that context.  Otherwise, return 2 since it might be
    486  1.1  mrg          used there later.  All other constants take at least two
    487  1.1  mrg          insns.  */
    488  1.1  mrg       if (satisfies_constraint_I (x))
    489  1.1  mrg 	{
    490  1.1  mrg 	  *total = 0;
    491  1.1  mrg 	  return true;
    492  1.1  mrg 	}
    493  1.1  mrg       else if (outer_code == PLUS && add_operand (x, VOIDmode))
    494  1.1  mrg 	{
    495  1.1  mrg 	  /* Slightly penalize large constants even though we can add
    496  1.1  mrg 	     them in one instruction, because it forces the use of
    497  1.1  mrg 	     2-wide bundling mode.  */
    498  1.1  mrg 	  *total = 1;
    499  1.1  mrg 	  return true;
    500  1.1  mrg 	}
    501  1.1  mrg       else if (move_operand (x, SImode))
    502  1.1  mrg 	{
    503  1.1  mrg 	  /* We can materialize in one move.  */
    504  1.1  mrg 	  *total = COSTS_N_INSNS (1);
    505  1.1  mrg 	  return true;
    506  1.1  mrg 	}
    507  1.1  mrg       else
    508  1.1  mrg 	{
    509  1.1  mrg 	  /* We can materialize in two moves.  */
    510  1.1  mrg 	  *total = COSTS_N_INSNS (2);
    511  1.1  mrg 	  return true;
    512  1.1  mrg 	}
    513  1.1  mrg 
    514  1.1  mrg       return false;
    515  1.1  mrg 
    516  1.1  mrg     case CONST:
    517  1.1  mrg     case LABEL_REF:
    518  1.1  mrg     case SYMBOL_REF:
    519  1.1  mrg       *total = COSTS_N_INSNS (2);
    520  1.1  mrg       return true;
    521  1.1  mrg 
    522  1.1  mrg     case CONST_DOUBLE:
    523  1.1  mrg       *total = COSTS_N_INSNS (4);
    524  1.1  mrg       return true;
    525  1.1  mrg 
    526  1.1  mrg     case HIGH:
    527  1.1  mrg       *total = 0;
    528  1.1  mrg       return true;
    529  1.1  mrg 
    530  1.1  mrg     case MEM:
    531  1.1  mrg       /* If outer-code was a sign or zero extension, a cost of
    532  1.1  mrg          COSTS_N_INSNS (1) was already added in, so account for
    533  1.1  mrg          that.  */
    534  1.1  mrg       if (outer_code == ZERO_EXTEND || outer_code == SIGN_EXTEND)
    535  1.1  mrg 	*total = COSTS_N_INSNS (1);
    536  1.1  mrg       else
    537  1.1  mrg 	*total = COSTS_N_INSNS (2);
    538  1.1  mrg       return true;
    539  1.1  mrg 
    540  1.1  mrg     case PLUS:
    541  1.1  mrg       /* Convey that s[123]a are efficient.  */
    542  1.1  mrg       if (GET_CODE (XEXP (x, 0)) == MULT
    543  1.1  mrg 	  && cint_248_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
    544  1.1  mrg 	{
    545  1.1  mrg 	  *total = (rtx_cost (XEXP (XEXP (x, 0), 0), mode,
    546  1.1  mrg 			      (enum rtx_code) outer_code, opno, speed)
    547  1.1  mrg 		    + rtx_cost (XEXP (x, 1), mode,
    548  1.1  mrg 				(enum rtx_code) outer_code, opno, speed)
    549  1.1  mrg 		    + COSTS_N_INSNS (1));
    550  1.1  mrg 	  return true;
    551  1.1  mrg 	}
    552  1.1  mrg       return false;
    553  1.1  mrg 
    554  1.1  mrg     case MULT:
    555  1.1  mrg       *total = COSTS_N_INSNS (2);
    556  1.1  mrg       return false;
    557  1.1  mrg 
    558  1.1  mrg     case SIGN_EXTEND:
    559  1.1  mrg     case ZERO_EXTEND:
    560  1.1  mrg       if (outer_code == MULT)
    561  1.1  mrg 	*total = 0;
    562  1.1  mrg       else
    563  1.1  mrg 	*total = COSTS_N_INSNS (1);
    564  1.1  mrg       return false;
    565  1.1  mrg 
    566  1.1  mrg     case DIV:
    567  1.1  mrg     case UDIV:
    568  1.1  mrg     case MOD:
    569  1.1  mrg     case UMOD:
    570  1.1  mrg       /* These are handled by software and are very expensive.  */
    571  1.1  mrg       *total = COSTS_N_INSNS (100);
    572  1.1  mrg       return false;
    573  1.1  mrg 
    574  1.1  mrg     case UNSPEC:
    575  1.1  mrg     case UNSPEC_VOLATILE:
    576  1.1  mrg       {
    577  1.1  mrg 	int num = XINT (x, 1);
    578  1.1  mrg 
    579  1.1  mrg 	if (num <= TILEPRO_LAST_LATENCY_1_INSN)
    580  1.1  mrg 	  *total = COSTS_N_INSNS (1);
    581  1.1  mrg 	else if (num <= TILEPRO_LAST_LATENCY_2_INSN)
    582  1.1  mrg 	  *total = COSTS_N_INSNS (2);
    583  1.1  mrg 	else if (num > TILEPRO_LAST_LATENCY_INSN)
    584  1.1  mrg 	  {
    585  1.1  mrg 	    if (outer_code == PLUS)
    586  1.1  mrg 	      *total = 0;
    587  1.1  mrg 	    else
    588  1.1  mrg 	      *total = COSTS_N_INSNS (1);
    589  1.1  mrg 	  }
    590  1.1  mrg 	else
    591  1.1  mrg 	  {
    592  1.1  mrg 	    switch (num)
    593  1.1  mrg 	      {
    594  1.1  mrg 	      case UNSPEC_BLOCKAGE:
    595  1.1  mrg 	      case UNSPEC_NETWORK_BARRIER:
    596  1.1  mrg 		*total = 0;
    597  1.1  mrg 		break;
    598  1.1  mrg 
    599  1.1  mrg 	      case UNSPEC_LNK_AND_LABEL:
    600  1.1  mrg 	      case UNSPEC_MF:
    601  1.1  mrg 	      case UNSPEC_NETWORK_RECEIVE:
    602  1.1  mrg 	      case UNSPEC_NETWORK_SEND:
    603  1.1  mrg 	      case UNSPEC_TLS_GD_ADD:
    604  1.1  mrg 		*total = COSTS_N_INSNS (1);
    605  1.1  mrg 		break;
    606  1.1  mrg 
    607  1.1  mrg 	      case UNSPEC_TLS_IE_LOAD:
    608  1.1  mrg 		*total = COSTS_N_INSNS (2);
    609  1.1  mrg 		break;
    610  1.1  mrg 
    611  1.1  mrg 	      case UNSPEC_SP_SET:
    612  1.1  mrg 		*total = COSTS_N_INSNS (3);
    613  1.1  mrg 		break;
    614  1.1  mrg 
    615  1.1  mrg 	      case UNSPEC_SP_TEST:
    616  1.1  mrg 		*total = COSTS_N_INSNS (4);
    617  1.1  mrg 		break;
    618  1.1  mrg 
    619  1.1  mrg 	      case UNSPEC_LATENCY_L2:
    620  1.1  mrg 		*total = COSTS_N_INSNS (8);
    621  1.1  mrg 		break;
    622  1.1  mrg 
    623  1.1  mrg 	      case UNSPEC_TLS_GD_CALL:
    624  1.1  mrg 		*total = COSTS_N_INSNS (30);
    625  1.1  mrg 		break;
    626  1.1  mrg 
    627  1.1  mrg 	      case UNSPEC_LATENCY_MISS:
    628  1.1  mrg 		*total = COSTS_N_INSNS (80);
    629  1.1  mrg 		break;
    630  1.1  mrg 
    631  1.1  mrg 	      default:
    632  1.1  mrg 		*total = COSTS_N_INSNS (1);
    633  1.1  mrg 	      }
    634  1.1  mrg 	  }
    635  1.1  mrg 	return true;
    636  1.1  mrg       }
    637  1.1  mrg 
    638  1.1  mrg     default:
    639  1.1  mrg       return false;
    640  1.1  mrg     }
    641  1.1  mrg }
    642  1.1  mrg 
    643  1.1  mrg 
    645  1.1  mrg 
    646  1.1  mrg /* Returns an SImode integer rtx with value VAL.  */
    647  1.1  mrg static rtx
    648  1.1  mrg gen_int_si (HOST_WIDE_INT val)
    649  1.1  mrg {
    650  1.1  mrg   return gen_int_mode (val, SImode);
    651  1.1  mrg }
    652  1.1  mrg 
    653  1.1  mrg 
    654  1.1  mrg /* Create a temporary variable to hold a partial result, to enable
    655  1.1  mrg    CSE.  */
    656  1.1  mrg static rtx
    657  1.1  mrg create_temp_reg_if_possible (machine_mode mode, rtx default_reg)
    658  1.1  mrg {
    659  1.1  mrg   return can_create_pseudo_p ()? gen_reg_rtx (mode) : default_reg;
    660  1.1  mrg }
    661  1.1  mrg 
    662  1.1  mrg 
    663  1.1  mrg /* Functions to save and restore machine-specific function data.  */
    664  1.1  mrg static struct machine_function *
    665  1.1  mrg tilepro_init_machine_status (void)
    666  1.1  mrg {
    667  1.1  mrg   return ggc_cleared_alloc<machine_function> ();
    668  1.1  mrg }
    669  1.1  mrg 
    670  1.1  mrg 
    671  1.1  mrg /* Do anything needed before RTL is emitted for each function.  */
    672  1.1  mrg void
    673  1.1  mrg tilepro_init_expanders (void)
    674  1.1  mrg {
    675  1.1  mrg   /* Arrange to initialize and mark the machine per-function
    676  1.1  mrg      status.  */
    677  1.1  mrg   init_machine_status = tilepro_init_machine_status;
    678  1.1  mrg 
    679  1.1  mrg   if (cfun && cfun->machine && flag_pic)
    680  1.1  mrg     {
    681  1.1  mrg       static int label_num = 0;
    682  1.1  mrg 
    683  1.1  mrg       char text_label_name[32];
    684  1.1  mrg 
    685  1.1  mrg       struct machine_function *machine = cfun->machine;
    686  1.1  mrg 
    687  1.1  mrg       ASM_GENERATE_INTERNAL_LABEL (text_label_name, "L_PICLNK", label_num++);
    688  1.1  mrg 
    689  1.1  mrg       machine->text_label_symbol =
    690  1.1  mrg 	gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (text_label_name));
    691  1.1  mrg 
    692  1.1  mrg       machine->text_label_rtx =
    693  1.1  mrg 	gen_rtx_REG (Pmode, TILEPRO_PIC_TEXT_LABEL_REGNUM);
    694  1.1  mrg 
    695  1.1  mrg       machine->got_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
    696  1.1  mrg 
    697  1.1  mrg       machine->calls_tls_get_addr = false;
    698  1.1  mrg     }
    699  1.1  mrg }
    700  1.1  mrg 
    701  1.1  mrg 
    702  1.1  mrg /* Return true if X contains a thread-local symbol.  */
    703  1.1  mrg static bool
    704  1.1  mrg tilepro_tls_referenced_p (rtx x)
    705  1.1  mrg {
    706  1.1  mrg   if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
    707  1.1  mrg     x = XEXP (XEXP (x, 0), 0);
    708  1.1  mrg 
    709  1.1  mrg   if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
    710  1.1  mrg     return true;
    711  1.1  mrg 
    712  1.1  mrg   /* That's all we handle in tilepro_legitimize_tls_address for
    713  1.1  mrg      now.  */
    714  1.1  mrg   return false;
    715  1.1  mrg }
    716  1.1  mrg 
    717  1.1  mrg 
    718  1.1  mrg /* Return true if X requires a scratch register.  It is given that
    719  1.1  mrg    flag_pic is on and that X satisfies CONSTANT_P.  */
    720  1.1  mrg static int
    721  1.1  mrg tilepro_pic_address_needs_scratch (rtx x)
    722  1.1  mrg {
    723  1.1  mrg   if (GET_CODE (x) == CONST
    724  1.1  mrg       && GET_CODE (XEXP (x, 0)) == PLUS
    725  1.1  mrg       && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
    726  1.1  mrg 	  || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
    727  1.1  mrg       && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
    728  1.1  mrg     return true;
    729  1.1  mrg 
    730  1.1  mrg   return false;
    731  1.1  mrg }
    732  1.1  mrg 
    733  1.1  mrg 
    734  1.1  mrg /* Implement TARGET_LEGITIMATE_CONSTANT_P.  This is all constants for
    735  1.1  mrg    which we are willing to load the value into a register via a move
    736  1.1  mrg    pattern.  TLS cannot be treated as a constant because it can
    737  1.1  mrg    include a function call.  */
    738  1.1  mrg static bool
    739  1.1  mrg tilepro_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
    740  1.1  mrg {
    741  1.1  mrg   switch (GET_CODE (x))
    742  1.1  mrg     {
    743  1.1  mrg     case CONST:
    744  1.1  mrg     case SYMBOL_REF:
    745  1.1  mrg       return !tilepro_tls_referenced_p (x);
    746  1.1  mrg 
    747  1.1  mrg     default:
    748  1.1  mrg       return true;
    749  1.1  mrg     }
    750  1.1  mrg }
    751  1.1  mrg 
    752  1.1  mrg 
    753  1.1  mrg /* Return true if the constant value X is a legitimate general operand
    754  1.1  mrg    when generating PIC code.  It is given that flag_pic is on and that
    755  1.1  mrg    X satisfies CONSTANT_P.  */
    756  1.1  mrg bool
    757  1.1  mrg tilepro_legitimate_pic_operand_p (rtx x)
    758  1.1  mrg {
    759  1.1  mrg   if (tilepro_pic_address_needs_scratch (x))
    760  1.1  mrg     return false;
    761  1.1  mrg 
    762  1.1  mrg   if (tilepro_tls_referenced_p (x))
    763  1.1  mrg     return false;
    764  1.1  mrg 
    765  1.1  mrg   return true;
    766  1.1  mrg }
    767  1.1  mrg 
    768  1.1  mrg 
    769  1.1  mrg /* Return true if the rtx X can be used as an address operand.  */
    770  1.1  mrg static bool
    771  1.1  mrg tilepro_legitimate_address_p (machine_mode ARG_UNUSED (mode), rtx x,
    772  1.1  mrg 			      bool strict)
    773  1.1  mrg {
    774  1.1  mrg   if (GET_CODE (x) == SUBREG)
    775  1.1  mrg     x = SUBREG_REG (x);
    776  1.1  mrg 
    777  1.1  mrg   switch (GET_CODE (x))
    778  1.1  mrg     {
    779  1.1  mrg     case POST_INC:
    780  1.1  mrg     case POST_DEC:
    781  1.1  mrg       if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
    782  1.1  mrg 	return false;
    783  1.1  mrg 
    784  1.1  mrg       x = XEXP (x, 0);
    785  1.1  mrg       break;
    786  1.1  mrg 
    787  1.1  mrg     case POST_MODIFY:
    788  1.1  mrg       if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
    789  1.1  mrg 	return false;
    790  1.1  mrg 
    791  1.1  mrg       if (GET_CODE (XEXP (x, 1)) != PLUS)
    792  1.1  mrg 	return false;
    793  1.1  mrg 
    794  1.1  mrg       if (!rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0)))
    795  1.1  mrg 	return false;
    796  1.1  mrg 
    797  1.1  mrg       if (!satisfies_constraint_I (XEXP (XEXP (x, 1), 1)))
    798  1.1  mrg 	return false;
    799  1.1  mrg 
    800  1.1  mrg       x = XEXP (x, 0);
    801  1.1  mrg       break;
    802  1.1  mrg 
    803  1.1  mrg     case REG:
    804  1.1  mrg       break;
    805  1.1  mrg 
    806  1.1  mrg     default:
    807  1.1  mrg       return false;
    808  1.1  mrg     }
    809  1.1  mrg 
    810  1.1  mrg   /* Check if x is a valid reg.  */
    811  1.1  mrg   if (!REG_P (x))
    812  1.1  mrg     return false;
    813  1.1  mrg 
    814  1.1  mrg   if (strict)
    815  1.1  mrg     return REGNO_OK_FOR_BASE_P (REGNO (x));
    816  1.1  mrg   else
    817  1.1  mrg     return true;
    818  1.1  mrg }
    819  1.1  mrg 
    820  1.1  mrg 
    821  1.1  mrg /* Return the rtx containing SYMBOL_REF to the text label.  */
    822  1.1  mrg static rtx
    823  1.1  mrg tilepro_text_label_symbol (void)
    824  1.1  mrg {
    825  1.1  mrg   return cfun->machine->text_label_symbol;
    826  1.1  mrg }
    827  1.1  mrg 
    828  1.1  mrg 
    829  1.1  mrg /* Return the register storing the value of the text label.  */
    830  1.1  mrg static rtx
    831  1.1  mrg tilepro_text_label_rtx (void)
    832  1.1  mrg {
    833  1.1  mrg   return cfun->machine->text_label_rtx;
    834  1.1  mrg }
    835  1.1  mrg 
    836  1.1  mrg 
    837  1.1  mrg /* Return the register storing the value of the global offset
    838  1.1  mrg    table.  */
    839  1.1  mrg static rtx
    840  1.1  mrg tilepro_got_rtx (void)
    841  1.1  mrg {
    842  1.1  mrg   return cfun->machine->got_rtx;
    843  1.1  mrg }
    844  1.1  mrg 
    845  1.1  mrg 
    846  1.1  mrg /* Return the SYMBOL_REF for _GLOBAL_OFFSET_TABLE_.  */
    847  1.1  mrg static rtx
    848  1.1  mrg tilepro_got_symbol (void)
    849  1.1  mrg {
    850  1.1  mrg   if (g_got_symbol == NULL)
    851  1.1  mrg     g_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
    852  1.1  mrg 
    853  1.1  mrg   return g_got_symbol;
    854  1.1  mrg }
    855  1.1  mrg 
    856  1.1  mrg 
    857  1.1  mrg /* Return a reference to the got to be used by tls references.  */
    858  1.1  mrg static rtx
    859  1.1  mrg tilepro_tls_got (void)
    860  1.1  mrg {
    861  1.1  mrg   rtx temp;
    862  1.1  mrg   if (flag_pic)
    863  1.1  mrg     {
    864  1.1  mrg       crtl->uses_pic_offset_table = 1;
    865  1.1  mrg       return tilepro_got_rtx ();
    866  1.1  mrg     }
    867  1.1  mrg 
    868  1.1  mrg   temp = gen_reg_rtx (Pmode);
    869  1.1  mrg   emit_move_insn (temp, tilepro_got_symbol ());
    870  1.1  mrg 
    871  1.1  mrg   return temp;
    872  1.1  mrg }
    873  1.1  mrg 
    874  1.1  mrg 
    875  1.1  mrg /* ADDR contains a thread-local SYMBOL_REF.  Generate code to compute
    876  1.1  mrg    this (thread-local) address.  */
    877  1.1  mrg static rtx
    878  1.1  mrg tilepro_legitimize_tls_address (rtx addr)
    879  1.1  mrg {
    880  1.1  mrg   rtx ret;
    881  1.1  mrg 
    882  1.1  mrg   gcc_assert (can_create_pseudo_p ());
    883  1.1  mrg 
    884  1.1  mrg   if (GET_CODE (addr) == SYMBOL_REF)
    885  1.1  mrg     switch (SYMBOL_REF_TLS_MODEL (addr))
    886  1.1  mrg       {
    887  1.1  mrg       case TLS_MODEL_GLOBAL_DYNAMIC:
    888  1.1  mrg       case TLS_MODEL_LOCAL_DYNAMIC:
    889  1.1  mrg 	{
    890  1.1  mrg 	  rtx r0, temp1, temp2, temp3, got;
    891  1.1  mrg 	  rtx_insn *last;
    892  1.1  mrg 
    893  1.1  mrg 	  ret = gen_reg_rtx (Pmode);
    894  1.1  mrg 	  r0 = gen_rtx_REG (Pmode, 0);
    895  1.1  mrg 	  temp1 = gen_reg_rtx (Pmode);
    896  1.1  mrg 	  temp2 = gen_reg_rtx (Pmode);
    897  1.1  mrg 	  temp3 = gen_reg_rtx (Pmode);
    898  1.1  mrg 
    899  1.1  mrg 	  got = tilepro_tls_got ();
    900  1.1  mrg 	  emit_insn (gen_tls_gd_addhi (temp1, got, addr));
    901  1.1  mrg 	  emit_insn (gen_tls_gd_addlo (temp2, temp1, addr));
    902  1.1  mrg 	  emit_move_insn (r0, temp2);
    903  1.1  mrg 	  emit_insn (gen_tls_gd_call (addr));
    904  1.1  mrg 	  emit_move_insn (temp3, r0);
    905  1.1  mrg 	  last = emit_insn (gen_tls_gd_add (ret, temp3, addr));
    906  1.1  mrg 	  set_unique_reg_note (last, REG_EQUAL, copy_rtx (addr));
    907  1.1  mrg 	  break;
    908  1.1  mrg 	}
    909  1.1  mrg       case TLS_MODEL_INITIAL_EXEC:
    910  1.1  mrg 	{
    911  1.1  mrg 	  rtx temp1, temp2, temp3, got;
    912  1.1  mrg 	  rtx_insn *last;
    913  1.1  mrg 
    914  1.1  mrg 	  ret = gen_reg_rtx (Pmode);
    915  1.1  mrg 	  temp1 = gen_reg_rtx (Pmode);
    916  1.1  mrg 	  temp2 = gen_reg_rtx (Pmode);
    917  1.1  mrg 	  temp3 = gen_reg_rtx (Pmode);
    918  1.1  mrg 
    919  1.1  mrg 	  got = tilepro_tls_got ();
    920  1.1  mrg 	  emit_insn (gen_tls_ie_addhi (temp1, got, addr));
    921  1.1  mrg 	  emit_insn (gen_tls_ie_addlo (temp2, temp1, addr));
    922  1.1  mrg 	  emit_insn (gen_tls_ie_load (temp3, temp2, addr));
    923  1.1  mrg 	  last =
    924  1.1  mrg 	    emit_move_insn(ret,
    925  1.1  mrg 			   gen_rtx_PLUS (Pmode,
    926  1.1  mrg 					 gen_rtx_REG (Pmode,
    927  1.1  mrg 						      THREAD_POINTER_REGNUM),
    928  1.1  mrg 					 temp3));
    929  1.1  mrg 	  set_unique_reg_note (last, REG_EQUAL, copy_rtx (addr));
    930  1.1  mrg 	  break;
    931  1.1  mrg 	}
    932  1.1  mrg       case TLS_MODEL_LOCAL_EXEC:
    933  1.1  mrg 	{
    934  1.1  mrg 	  rtx temp1;
    935  1.1  mrg 	  rtx_insn *last;
    936  1.1  mrg 
    937  1.1  mrg 	  ret = gen_reg_rtx (Pmode);
    938  1.1  mrg 	  temp1 = gen_reg_rtx (Pmode);
    939  1.1  mrg 
    940  1.1  mrg 	  emit_insn (gen_tls_le_addhi (temp1,
    941  1.1  mrg 				       gen_rtx_REG (Pmode,
    942  1.1  mrg 						    THREAD_POINTER_REGNUM),
    943  1.1  mrg 				       addr));
    944  1.1  mrg 	  last = emit_insn (gen_tls_le_addlo (ret, temp1, addr));
    945  1.1  mrg 	  set_unique_reg_note (last, REG_EQUAL, copy_rtx (addr));
    946  1.1  mrg 	  break;
    947  1.1  mrg 	}
    948  1.1  mrg       default:
    949  1.1  mrg 	gcc_unreachable ();
    950  1.1  mrg       }
    951  1.1  mrg   else if (GET_CODE (addr) == CONST)
    952  1.1  mrg     {
    953  1.1  mrg       rtx base, offset;
    954  1.1  mrg 
    955  1.1  mrg       gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS);
    956  1.1  mrg 
    957  1.1  mrg       base = tilepro_legitimize_tls_address (XEXP (XEXP (addr, 0), 0));
    958  1.1  mrg       offset = XEXP (XEXP (addr, 0), 1);
    959  1.1  mrg 
    960  1.1  mrg       base = force_operand (base, NULL_RTX);
    961  1.1  mrg       ret = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, offset));
    962  1.1  mrg     }
    963  1.1  mrg   else
    964  1.1  mrg     gcc_unreachable ();
    965  1.1  mrg 
    966  1.1  mrg   return ret;
    967  1.1  mrg }
    968  1.1  mrg 
    969  1.1  mrg 
    970  1.1  mrg /* Legitimize PIC addresses.  If the address is already
    971  1.1  mrg    position-independent, we return ORIG.  Newly generated
    972  1.1  mrg    position-independent addresses go into a reg.  This is REG if
    973  1.1  mrg    nonzero, otherwise we allocate register(s) as necessary.  */
    974  1.1  mrg static rtx
    975  1.1  mrg tilepro_legitimize_pic_address (rtx orig,
    976  1.1  mrg 				machine_mode mode ATTRIBUTE_UNUSED,
    977  1.1  mrg 				rtx reg)
    978  1.1  mrg {
    979  1.1  mrg   if (GET_CODE (orig) == SYMBOL_REF)
    980  1.1  mrg     {
    981  1.1  mrg       rtx address, pic_ref;
    982  1.1  mrg 
    983  1.1  mrg       if (reg == 0)
    984  1.1  mrg 	{
    985  1.1  mrg 	  gcc_assert (can_create_pseudo_p ());
    986  1.1  mrg 	  reg = gen_reg_rtx (Pmode);
    987  1.1  mrg 	}
    988  1.1  mrg 
    989  1.1  mrg       if (SYMBOL_REF_LOCAL_P (orig))
    990  1.1  mrg 	{
    991  1.1  mrg 	  /* If not during reload, allocate another temp reg here for
    992  1.1  mrg 	     loading in the address, so that these instructions can be
    993  1.1  mrg 	     optimized properly.  */
    994  1.1  mrg 	  rtx temp_reg = create_temp_reg_if_possible (Pmode, reg);
    995  1.1  mrg 	  rtx text_label_symbol = tilepro_text_label_symbol ();
    996  1.1  mrg 	  rtx text_label_rtx = tilepro_text_label_rtx ();
    997  1.1  mrg 
    998  1.1  mrg 	  emit_insn (gen_addli_pcrel (temp_reg, text_label_rtx, orig,
    999  1.1  mrg 				      text_label_symbol));
   1000  1.1  mrg 	  emit_insn (gen_auli_pcrel (temp_reg, temp_reg, orig,
   1001  1.1  mrg 				     text_label_symbol));
   1002  1.1  mrg 
   1003  1.1  mrg 	  /* Note: this is conservative.  We use the text_label but we
   1004  1.1  mrg 	     don't use the pic_offset_table.  However, in some cases
   1005  1.1  mrg 	     we may need the pic_offset_table (see
   1006  1.1  mrg 	     tilepro_fixup_pcrel_references).  */
   1007  1.1  mrg 	  crtl->uses_pic_offset_table = 1;
   1008  1.1  mrg 
   1009  1.1  mrg 	  address = temp_reg;
   1010  1.1  mrg 
   1011  1.1  mrg 	  emit_move_insn (reg, address);
   1012  1.1  mrg 	  return reg;
   1013  1.1  mrg 	}
   1014  1.1  mrg       else
   1015  1.1  mrg 	{
   1016  1.1  mrg 	  /* If not during reload, allocate another temp reg here for
   1017  1.1  mrg 	     loading in the address, so that these instructions can be
   1018  1.1  mrg 	     optimized properly.  */
   1019  1.1  mrg 	  rtx temp_reg = create_temp_reg_if_possible (Pmode, reg);
   1020  1.1  mrg 
   1021  1.1  mrg 	  gcc_assert (flag_pic);
   1022  1.1  mrg 	  if (flag_pic == 1)
   1023  1.1  mrg 	    {
   1024  1.1  mrg 	      emit_insn (gen_add_got16 (temp_reg,
   1025  1.1  mrg 					tilepro_got_rtx (), orig));
   1026  1.1  mrg 	    }
   1027  1.1  mrg 	  else
   1028  1.1  mrg 	    {
   1029  1.1  mrg 	      rtx temp_reg2 = create_temp_reg_if_possible (Pmode, reg);
   1030  1.1  mrg 	      emit_insn (gen_addhi_got32 (temp_reg2,
   1031  1.1  mrg 					  tilepro_got_rtx (), orig));
   1032  1.1  mrg 	      emit_insn (gen_addlo_got32 (temp_reg, temp_reg2, orig));
   1033  1.1  mrg 	    }
   1034  1.1  mrg 
   1035  1.1  mrg 	  address = temp_reg;
   1036  1.1  mrg 
   1037  1.1  mrg 	  pic_ref = gen_const_mem (Pmode, address);
   1038  1.1  mrg 	  crtl->uses_pic_offset_table = 1;
   1039  1.1  mrg 	  emit_move_insn (reg, pic_ref);
   1040  1.1  mrg 	  /* The following put a REG_EQUAL note on this insn, so that
   1041  1.1  mrg 	     it can be optimized by loop.  But it causes the label to
   1042  1.1  mrg 	     be optimized away.  */
   1043  1.1  mrg 	  /* set_unique_reg_note (insn, REG_EQUAL, orig); */
   1044  1.1  mrg 	  return reg;
   1045  1.1  mrg 	}
   1046  1.1  mrg     }
   1047  1.1  mrg   else if (GET_CODE (orig) == CONST)
   1048  1.1  mrg     {
   1049  1.1  mrg       rtx base, offset;
   1050  1.1  mrg 
   1051  1.1  mrg       if (GET_CODE (XEXP (orig, 0)) == PLUS
   1052  1.1  mrg 	  && XEXP (XEXP (orig, 0), 0) == tilepro_got_rtx ())
   1053  1.1  mrg 	return orig;
   1054  1.1  mrg 
   1055  1.1  mrg       if (reg == 0)
   1056  1.1  mrg 	{
   1057  1.1  mrg 	  gcc_assert (can_create_pseudo_p ());
   1058  1.1  mrg 	  reg = gen_reg_rtx (Pmode);
   1059  1.1  mrg 	}
   1060  1.1  mrg 
   1061  1.1  mrg       gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
   1062  1.1  mrg       base = tilepro_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode,
   1063  1.1  mrg 					     reg);
   1064  1.1  mrg       offset =
   1065  1.1  mrg 	tilepro_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
   1066  1.1  mrg 					base == reg ? 0 : reg);
   1067  1.1  mrg 
   1068  1.1  mrg       if (CONST_INT_P (offset))
   1069  1.1  mrg 	{
   1070  1.1  mrg 	  if (can_create_pseudo_p ())
   1071  1.1  mrg 	    offset = force_reg (Pmode, offset);
   1072  1.1  mrg 	  else
   1073  1.1  mrg 	    /* If we reach here, then something is seriously
   1074  1.1  mrg 	       wrong.  */
   1075  1.1  mrg 	    gcc_unreachable ();
   1076  1.1  mrg 	}
   1077  1.1  mrg 
   1078  1.1  mrg       if (can_create_pseudo_p ())
   1079  1.1  mrg 	return force_reg (Pmode, gen_rtx_PLUS (Pmode, base, offset));
   1080  1.1  mrg       else
   1081  1.1  mrg 	gcc_unreachable ();
   1082  1.1  mrg     }
   1083  1.1  mrg   else if (GET_CODE (orig) == LABEL_REF)
   1084  1.1  mrg     {
   1085  1.1  mrg       rtx address, temp_reg;
   1086  1.1  mrg       rtx text_label_symbol;
   1087  1.1  mrg       rtx text_label_rtx;
   1088  1.1  mrg 
   1089  1.1  mrg       if (reg == 0)
   1090  1.1  mrg 	{
   1091  1.1  mrg 	  gcc_assert (can_create_pseudo_p ());
   1092  1.1  mrg 	  reg = gen_reg_rtx (Pmode);
   1093  1.1  mrg 	}
   1094  1.1  mrg 
   1095  1.1  mrg       /* If not during reload, allocate another temp reg here for
   1096  1.1  mrg          loading in the address, so that these instructions can be
   1097  1.1  mrg          optimized properly.  */
   1098  1.1  mrg       temp_reg = create_temp_reg_if_possible (Pmode, reg);
   1099  1.1  mrg       text_label_symbol = tilepro_text_label_symbol ();
   1100  1.1  mrg       text_label_rtx = tilepro_text_label_rtx ();
   1101  1.1  mrg 
   1102  1.1  mrg       emit_insn (gen_addli_pcrel (temp_reg, text_label_rtx, orig,
   1103  1.1  mrg 				  text_label_symbol));
   1104  1.1  mrg       emit_insn (gen_auli_pcrel (temp_reg, temp_reg, orig,
   1105  1.1  mrg 				 text_label_symbol));
   1106  1.1  mrg 
   1107  1.1  mrg       /* Note: this is conservative.  We use the text_label but we
   1108  1.1  mrg          don't use the pic_offset_table.  */
   1109  1.1  mrg       crtl->uses_pic_offset_table = 1;
   1110  1.1  mrg 
   1111  1.1  mrg       address = temp_reg;
   1112  1.1  mrg 
   1113  1.1  mrg       emit_move_insn (reg, address);
   1114  1.1  mrg 
   1115  1.1  mrg       return reg;
   1116  1.1  mrg     }
   1117  1.1  mrg 
   1118  1.1  mrg   return orig;
   1119  1.1  mrg }
   1120  1.1  mrg 
   1121  1.1  mrg 
   1122  1.1  mrg /* Implement TARGET_LEGITIMIZE_ADDRESS.  */
   1123  1.1  mrg static rtx
   1124  1.1  mrg tilepro_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
   1125  1.1  mrg 			    machine_mode mode)
   1126  1.1  mrg {
   1127  1.1  mrg   if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
   1128  1.1  mrg       && symbolic_operand (x, Pmode) && tilepro_tls_referenced_p (x))
   1129  1.1  mrg     {
   1130  1.1  mrg       return tilepro_legitimize_tls_address (x);
   1131  1.1  mrg     }
   1132  1.1  mrg   else if (flag_pic)
   1133  1.1  mrg     {
   1134  1.1  mrg       return tilepro_legitimize_pic_address (x, mode, 0);
   1135  1.1  mrg     }
   1136  1.1  mrg   else
   1137  1.1  mrg     return x;
   1138  1.1  mrg }
   1139  1.1  mrg 
   1140  1.1  mrg 
   1141  1.1  mrg /* Implement TARGET_DELEGITIMIZE_ADDRESS.  */
   1142  1.1  mrg static rtx
   1143  1.1  mrg tilepro_delegitimize_address (rtx x)
   1144  1.1  mrg {
   1145  1.1  mrg   x = delegitimize_mem_from_attrs (x);
   1146  1.1  mrg 
   1147  1.1  mrg   if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
   1148  1.1  mrg     {
   1149  1.1  mrg       switch (XINT (XEXP (x, 0), 1))
   1150  1.1  mrg 	{
   1151  1.1  mrg 	case UNSPEC_PCREL_SYM:
   1152  1.1  mrg 	case UNSPEC_GOT16_SYM:
   1153  1.1  mrg 	case UNSPEC_GOT32_SYM:
   1154  1.1  mrg 	case UNSPEC_TLS_GD:
   1155  1.1  mrg 	case UNSPEC_TLS_IE:
   1156  1.1  mrg 	  x = XVECEXP (XEXP (x, 0), 0, 0);
   1157  1.1  mrg 	  break;
   1158  1.1  mrg 	}
   1159  1.1  mrg     }
   1160  1.1  mrg 
   1161  1.1  mrg   return x;
   1162  1.1  mrg }
   1163  1.1  mrg 
   1164  1.1  mrg 
   1165  1.1  mrg /* Emit code to load the PIC register.  */
   1166  1.1  mrg static void
   1167  1.1  mrg load_pic_register (bool delay_pic_helper ATTRIBUTE_UNUSED)
   1168  1.1  mrg {
   1169  1.1  mrg   int orig_flag_pic = flag_pic;
   1170  1.1  mrg 
   1171  1.1  mrg   rtx got_symbol = tilepro_got_symbol ();
   1172  1.1  mrg   rtx text_label_symbol = tilepro_text_label_symbol ();
   1173  1.1  mrg   rtx text_label_rtx = tilepro_text_label_rtx ();
   1174  1.1  mrg   flag_pic = 0;
   1175  1.1  mrg 
   1176  1.1  mrg   emit_insn (gen_insn_lnk_and_label (text_label_rtx, text_label_symbol));
   1177  1.1  mrg 
   1178  1.1  mrg   emit_insn (gen_addli_pcrel (tilepro_got_rtx (),
   1179  1.1  mrg 			      text_label_rtx, got_symbol, text_label_symbol));
   1180  1.1  mrg 
   1181  1.1  mrg   emit_insn (gen_auli_pcrel (tilepro_got_rtx (),
   1182  1.1  mrg 			     tilepro_got_rtx (),
   1183  1.1  mrg 			     got_symbol, text_label_symbol));
   1184  1.1  mrg 
   1185  1.1  mrg   flag_pic = orig_flag_pic;
   1186  1.1  mrg 
   1187  1.1  mrg   /* Need to emit this whether or not we obey regdecls, since
   1188  1.1  mrg      setjmp/longjmp can cause life info to screw up.  ??? In the case
   1189  1.1  mrg      where we don't obey regdecls, this is not sufficient since we may
   1190  1.1  mrg      not fall out the bottom.  */
   1191  1.1  mrg   emit_use (tilepro_got_rtx ());
   1192  1.1  mrg }
   1193  1.1  mrg 
   1194  1.1  mrg 
   1195  1.1  mrg /* Return the simd variant of the constant NUM of mode MODE, by
   1196  1.1  mrg    replicating it to fill an interger of mode SImode.  NUM is first
   1197  1.1  mrg    truncated to fit in MODE.  */
   1198  1.1  mrg rtx
   1199  1.1  mrg tilepro_simd_int (rtx num, machine_mode mode)
   1200  1.1  mrg {
   1201  1.1  mrg   HOST_WIDE_INT n = 0;
   1202  1.1  mrg 
   1203  1.1  mrg   gcc_assert (CONST_INT_P (num));
   1204  1.1  mrg 
   1205  1.1  mrg   n = INTVAL (num);
   1206  1.1  mrg 
   1207  1.1  mrg   switch (mode)
   1208  1.1  mrg     {
   1209  1.1  mrg     case E_QImode:
   1210  1.1  mrg       n = 0x01010101 * (n & 0x000000FF);
   1211  1.1  mrg       break;
   1212  1.1  mrg     case E_HImode:
   1213  1.1  mrg       n = 0x00010001 * (n & 0x0000FFFF);
   1214  1.1  mrg       break;
   1215  1.1  mrg     case E_SImode:
   1216  1.1  mrg       break;
   1217  1.1  mrg     case E_DImode:
   1218  1.1  mrg       break;
   1219  1.1  mrg     default:
   1220  1.1  mrg       gcc_unreachable ();
   1221  1.1  mrg     }
   1222  1.1  mrg 
   1223  1.1  mrg   return gen_int_si (n);
   1224  1.1  mrg }
   1225  1.1  mrg 
   1226  1.1  mrg 
   1227  1.1  mrg /* Split one or more DImode RTL references into pairs of SImode
   1228  1.1  mrg    references.  The RTL can be REG, offsettable MEM, integer constant,
   1229  1.1  mrg    or CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL
   1230  1.1  mrg    to split and "num" is its length.  lo_half and hi_half are output
   1231  1.1  mrg    arrays that parallel "operands".  */
   1232  1.1  mrg void
   1233  1.1  mrg split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
   1234  1.1  mrg {
   1235  1.1  mrg   while (num--)
   1236  1.1  mrg     {
   1237  1.1  mrg       rtx op = operands[num];
   1238  1.1  mrg 
   1239  1.1  mrg       /* simplify_subreg refuse to split volatile memory addresses,
   1240  1.1  mrg          but we still have to handle it.  */
   1241  1.1  mrg       if (MEM_P (op))
   1242  1.1  mrg 	{
   1243  1.1  mrg 	  lo_half[num] = adjust_address (op, SImode, 0);
   1244  1.1  mrg 	  hi_half[num] = adjust_address (op, SImode, 4);
   1245  1.1  mrg 	}
   1246  1.1  mrg       else
   1247  1.1  mrg 	{
   1248  1.1  mrg 	  lo_half[num] = simplify_gen_subreg (SImode, op,
   1249  1.1  mrg 					      GET_MODE (op) == VOIDmode
   1250  1.1  mrg 					      ? DImode : GET_MODE (op), 0);
   1251  1.1  mrg 	  hi_half[num] = simplify_gen_subreg (SImode, op,
   1252  1.1  mrg 					      GET_MODE (op) == VOIDmode
   1253  1.1  mrg 					      ? DImode : GET_MODE (op), 4);
   1254  1.1  mrg 	}
   1255  1.1  mrg     }
   1256  1.1  mrg }
   1257  1.1  mrg 
   1258  1.1  mrg 
   1259  1.1  mrg /* Returns true iff val can be moved into a register in one
   1260  1.1  mrg    instruction.  And if it can, it emits the code to move the
   1261  1.1  mrg    constant.
   1262  1.1  mrg 
   1263  1.1  mrg    If three_wide_only is true, this insists on an instruction that
   1264  1.1  mrg    works in a bundle containing three instructions.  */
   1265  1.1  mrg static bool
   1266  1.1  mrg expand_set_cint32_one_inst (rtx dest_reg,
   1267  1.1  mrg 			    HOST_WIDE_INT val, bool three_wide_only)
   1268  1.1  mrg {
   1269  1.1  mrg   val = trunc_int_for_mode (val, SImode);
   1270  1.1  mrg 
   1271  1.1  mrg   if (val == trunc_int_for_mode (val, QImode))
   1272  1.1  mrg     {
   1273  1.1  mrg       /* Success! */
   1274  1.1  mrg       emit_move_insn (dest_reg, GEN_INT (val));
   1275  1.1  mrg       return true;
   1276  1.1  mrg     }
   1277  1.1  mrg   else if (!three_wide_only)
   1278  1.1  mrg     {
   1279  1.1  mrg       rtx imm_op = GEN_INT (val);
   1280  1.1  mrg 
   1281  1.1  mrg       if (satisfies_constraint_J (imm_op)
   1282  1.1  mrg 	  || satisfies_constraint_K (imm_op)
   1283  1.1  mrg 	  || satisfies_constraint_N (imm_op)
   1284  1.1  mrg 	  || satisfies_constraint_P (imm_op))
   1285  1.1  mrg 	{
   1286  1.1  mrg 	  emit_move_insn (dest_reg, imm_op);
   1287  1.1  mrg 	  return true;
   1288  1.1  mrg 	}
   1289  1.1  mrg     }
   1290  1.1  mrg 
   1291  1.1  mrg   return false;
   1292  1.1  mrg }
   1293  1.1  mrg 
   1294  1.1  mrg 
   1295  1.1  mrg /* Implement SImode rotatert.  */
   1296  1.1  mrg static HOST_WIDE_INT
   1297  1.1  mrg rotate_right (HOST_WIDE_INT n, int count)
   1298  1.1  mrg {
   1299  1.1  mrg   unsigned HOST_WIDE_INT x = n & 0xFFFFFFFF;
   1300  1.1  mrg   if (count == 0)
   1301  1.1  mrg     return x;
   1302  1.1  mrg   return ((x >> count) | (x << (32 - count))) & 0xFFFFFFFF;
   1303  1.1  mrg }
   1304  1.1  mrg 
   1305  1.1  mrg 
   1306  1.1  mrg /* Return true iff n contains exactly one contiguous sequence of 1
   1307  1.1  mrg    bits, possibly wrapping around from high bits to low bits.  */
   1308  1.1  mrg bool
   1309  1.1  mrg tilepro_bitfield_operand_p (HOST_WIDE_INT n, int *first_bit, int *last_bit)
   1310  1.1  mrg {
   1311  1.1  mrg   int i;
   1312  1.1  mrg 
   1313  1.1  mrg   if (n == 0)
   1314  1.1  mrg     return false;
   1315  1.1  mrg 
   1316  1.1  mrg   for (i = 0; i < 32; i++)
   1317  1.1  mrg     {
   1318  1.1  mrg       unsigned HOST_WIDE_INT x = rotate_right (n, i);
   1319  1.1  mrg       if (!(x & 1))
   1320  1.1  mrg 	continue;
   1321  1.1  mrg 
   1322  1.1  mrg       /* See if x is a power of two minus one, i.e. only consecutive 1
   1323  1.1  mrg          bits starting from bit 0.  */
   1324  1.1  mrg       if ((x & (x + 1)) == 0)
   1325  1.1  mrg 	{
   1326  1.1  mrg 	  if (first_bit != NULL)
   1327  1.1  mrg 	    *first_bit = i;
   1328  1.1  mrg 	  if (last_bit != NULL)
   1329  1.1  mrg 	    *last_bit = (i + exact_log2 (x ^ (x >> 1))) & 31;
   1330  1.1  mrg 
   1331  1.1  mrg 	  return true;
   1332  1.1  mrg 	}
   1333  1.1  mrg     }
   1334  1.1  mrg 
   1335  1.1  mrg   return false;
   1336  1.1  mrg }
   1337  1.1  mrg 
   1338  1.1  mrg 
   1339  1.1  mrg /* Create code to move the CONST_INT value in src_val to dest_reg.  */
   1340  1.1  mrg static void
   1341  1.1  mrg expand_set_cint32 (rtx dest_reg, rtx src_val)
   1342  1.1  mrg {
   1343  1.1  mrg   HOST_WIDE_INT val;
   1344  1.1  mrg   int leading_zeroes, trailing_zeroes;
   1345  1.1  mrg   int lower, upper;
   1346  1.1  mrg   int three_wide_only;
   1347  1.1  mrg   rtx temp;
   1348  1.1  mrg 
   1349  1.1  mrg   gcc_assert (CONST_INT_P (src_val));
   1350  1.1  mrg   val = trunc_int_for_mode (INTVAL (src_val), SImode);
   1351  1.1  mrg 
   1352  1.1  mrg   /* See if we can generate the constant in one instruction.  */
   1353  1.1  mrg   if (expand_set_cint32_one_inst (dest_reg, val, false))
   1354  1.1  mrg     return;
   1355  1.1  mrg 
   1356  1.1  mrg   /* Create a temporary variable to hold a partial result, to enable
   1357  1.1  mrg      CSE.  */
   1358  1.1  mrg   temp = create_temp_reg_if_possible (SImode, dest_reg);
   1359  1.1  mrg 
   1360  1.1  mrg   leading_zeroes = 31 - floor_log2 (val & 0xFFFFFFFF);
   1361  1.1  mrg   trailing_zeroes = exact_log2 (val & -val);
   1362  1.1  mrg 
   1363  1.1  mrg   lower = trunc_int_for_mode (val, HImode);
   1364  1.1  mrg   upper = trunc_int_for_mode ((val - lower) >> 16, HImode);
   1365  1.1  mrg 
   1366  1.1  mrg   /* First try all three-wide instructions that generate a constant
   1367  1.1  mrg      (i.e. movei) followed by various shifts and rotates. If none of
   1368  1.1  mrg      those work, try various two-wide ways of generating a constant
   1369  1.1  mrg      followed by various shifts and rotates.  */
   1370  1.1  mrg   for (three_wide_only = 1; three_wide_only >= 0; three_wide_only--)
   1371  1.1  mrg     {
   1372  1.1  mrg       int count;
   1373  1.1  mrg 
   1374  1.1  mrg       if (expand_set_cint32_one_inst (temp, val >> trailing_zeroes,
   1375  1.1  mrg 				      three_wide_only))
   1376  1.1  mrg 	{
   1377  1.1  mrg 	  /* 0xFFFFA500 becomes:
   1378  1.1  mrg 	     movei temp, 0xFFFFFFA5
   1379  1.1  mrg 	     shli dest, temp, 8  */
   1380  1.1  mrg 	  emit_move_insn (dest_reg,
   1381  1.1  mrg 			  gen_rtx_ASHIFT (SImode, temp,
   1382  1.1  mrg 					  GEN_INT (trailing_zeroes)));
   1383  1.1  mrg 	  return;
   1384  1.1  mrg 	}
   1385  1.1  mrg 
   1386  1.1  mrg       if (expand_set_cint32_one_inst (temp, val << leading_zeroes,
   1387  1.1  mrg 				      three_wide_only))
   1388  1.1  mrg 	{
   1389  1.1  mrg 	  /* 0x7FFFFFFF becomes:
   1390  1.1  mrg 	     movei temp, -2
   1391  1.1  mrg 	     shri dest, temp, 1  */
   1392  1.1  mrg 	  emit_move_insn (dest_reg,
   1393  1.1  mrg 			  gen_rtx_LSHIFTRT (SImode, temp,
   1394  1.1  mrg 					    GEN_INT (leading_zeroes)));
   1395  1.1  mrg 	  return;
   1396  1.1  mrg 	}
   1397  1.1  mrg 
   1398  1.1  mrg       /* Try rotating a one-instruction immediate, since rotate is
   1399  1.1  mrg          3-wide.  */
   1400  1.1  mrg       for (count = 1; count < 32; count++)
   1401  1.1  mrg 	{
   1402  1.1  mrg 	  HOST_WIDE_INT r = rotate_right (val, count);
   1403  1.1  mrg 	  if (expand_set_cint32_one_inst (temp, r, three_wide_only))
   1404  1.1  mrg 	    {
   1405  1.1  mrg 	      /* 0xFFA5FFFF becomes:
   1406  1.1  mrg 	         movei temp, 0xFFFFFFA5
   1407  1.1  mrg 	         rli dest, temp, 16  */
   1408  1.1  mrg 	      emit_move_insn (dest_reg,
   1409  1.1  mrg 			      gen_rtx_ROTATE (SImode, temp, GEN_INT (count)));
   1410  1.1  mrg 	      return;
   1411  1.1  mrg 	    }
   1412  1.1  mrg 	}
   1413  1.1  mrg 
   1414  1.1  mrg       if (lower == trunc_int_for_mode (lower, QImode))
   1415  1.1  mrg 	{
   1416  1.1  mrg 	  /* We failed to use two 3-wide instructions, but the low 16
   1417  1.1  mrg 	     bits are a small number so just use a 2-wide + 3-wide
   1418  1.1  mrg 	     auli + addi pair rather than anything more exotic.
   1419  1.1  mrg 
   1420  1.1  mrg 	     0x12340056 becomes:
   1421  1.1  mrg 	     auli temp, zero, 0x1234
   1422  1.1  mrg 	     addi dest, temp, 0x56  */
   1423  1.1  mrg 	  break;
   1424  1.1  mrg 	}
   1425  1.1  mrg     }
   1426  1.1  mrg 
   1427  1.1  mrg   /* Fallback case: use a auli + addli/addi pair.  */
   1428  1.1  mrg   emit_move_insn (temp, GEN_INT (upper << 16));
   1429  1.1  mrg   emit_move_insn (dest_reg, (gen_rtx_PLUS (SImode, temp, GEN_INT (lower))));
   1430  1.1  mrg }
   1431  1.1  mrg 
   1432  1.1  mrg 
   1433  1.1  mrg /* Load OP1, a 32-bit constant, into OP0, a register.  We know it
   1434  1.1  mrg    can't be done in one insn when we get here, the move expander
   1435  1.1  mrg    guarantees this.  */
   1436  1.1  mrg void
   1437  1.1  mrg tilepro_expand_set_const32 (rtx op0, rtx op1)
   1438  1.1  mrg {
   1439  1.1  mrg   machine_mode mode = GET_MODE (op0);
   1440  1.1  mrg   rtx temp;
   1441  1.1  mrg 
   1442  1.1  mrg   if (CONST_INT_P (op1))
   1443  1.1  mrg     {
   1444  1.1  mrg       /* TODO: I don't know if we want to split large constants now,
   1445  1.1  mrg          or wait until later (with a define_split).
   1446  1.1  mrg 
   1447  1.1  mrg          Does splitting early help CSE?  Does it harm other
   1448  1.1  mrg          optimizations that might fold loads? */
   1449  1.1  mrg       expand_set_cint32 (op0, op1);
   1450  1.1  mrg     }
   1451  1.1  mrg   else
   1452  1.1  mrg     {
   1453  1.1  mrg       temp = create_temp_reg_if_possible (mode, op0);
   1454  1.1  mrg 
   1455  1.1  mrg       /* A symbol, emit in the traditional way.  */
   1456  1.1  mrg       emit_move_insn (temp, gen_rtx_HIGH (mode, op1));
   1457  1.1  mrg       emit_move_insn (op0, gen_rtx_LO_SUM (mode, temp, op1));
   1458  1.1  mrg     }
   1459  1.1  mrg }
   1460  1.1  mrg 
   1461  1.1  mrg 
   1462  1.1  mrg /* Expand a move instruction.  Return true if all work is done.  */
   1463  1.1  mrg bool
   1464  1.1  mrg tilepro_expand_mov (machine_mode mode, rtx *operands)
   1465  1.1  mrg {
   1466  1.1  mrg   /* Handle sets of MEM first.  */
   1467  1.1  mrg   if (MEM_P (operands[0]))
   1468  1.1  mrg     {
   1469  1.1  mrg       if (can_create_pseudo_p ())
   1470  1.1  mrg 	operands[0] = validize_mem (operands[0]);
   1471  1.1  mrg 
   1472  1.1  mrg       if (reg_or_0_operand (operands[1], mode))
   1473  1.1  mrg 	return false;
   1474  1.1  mrg 
   1475  1.1  mrg       if (!reload_in_progress)
   1476  1.1  mrg 	operands[1] = force_reg (mode, operands[1]);
   1477  1.1  mrg     }
   1478  1.1  mrg 
   1479  1.1  mrg   /* Fixup TLS cases.  */
   1480  1.1  mrg   if (CONSTANT_P (operands[1]) && tilepro_tls_referenced_p (operands[1]))
   1481  1.1  mrg     {
   1482  1.1  mrg       operands[1] = tilepro_legitimize_tls_address (operands[1]);
   1483  1.1  mrg       return false;
   1484  1.1  mrg     }
   1485  1.1  mrg 
   1486  1.1  mrg   /* Fixup PIC cases.  */
   1487  1.1  mrg   if (flag_pic && CONSTANT_P (operands[1]))
   1488  1.1  mrg     {
   1489  1.1  mrg       if (tilepro_pic_address_needs_scratch (operands[1]))
   1490  1.1  mrg 	operands[1] = tilepro_legitimize_pic_address (operands[1], mode, 0);
   1491  1.1  mrg 
   1492  1.1  mrg       if (symbolic_operand (operands[1], mode))
   1493  1.1  mrg 	{
   1494  1.1  mrg 	  operands[1] = tilepro_legitimize_pic_address (operands[1],
   1495  1.1  mrg 							mode,
   1496  1.1  mrg 							(reload_in_progress ?
   1497  1.1  mrg 							 operands[0] :
   1498  1.1  mrg 							 NULL_RTX));
   1499  1.1  mrg 	  return false;
   1500  1.1  mrg 	}
   1501  1.1  mrg     }
   1502  1.1  mrg 
   1503  1.1  mrg   /* Fixup for UNSPEC addresses.  */
   1504  1.1  mrg   if (flag_pic
   1505  1.1  mrg       && GET_CODE (operands[1]) == HIGH
   1506  1.1  mrg       && GET_CODE (XEXP (operands[1], 0)) == CONST
   1507  1.1  mrg       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == UNSPEC)
   1508  1.1  mrg     {
   1509  1.1  mrg       rtx unspec = XEXP (XEXP (operands[1], 0), 0);
   1510  1.1  mrg       int unspec_num = XINT (unspec, 1);
   1511  1.1  mrg       if (unspec_num == UNSPEC_PCREL_SYM)
   1512  1.1  mrg 	{
   1513  1.1  mrg 	  emit_insn (gen_auli_pcrel (operands[0], const0_rtx,
   1514  1.1  mrg 				     XVECEXP (unspec, 0, 0),
   1515  1.1  mrg 				     XVECEXP (unspec, 0, 1)));
   1516  1.1  mrg 	  return true;
   1517  1.1  mrg 	}
   1518  1.1  mrg       else if (flag_pic == 2 && unspec_num == UNSPEC_GOT32_SYM)
   1519  1.1  mrg 	{
   1520  1.1  mrg 	  emit_insn (gen_addhi_got32 (operands[0], const0_rtx,
   1521  1.1  mrg 				      XVECEXP (unspec, 0, 0)));
   1522  1.1  mrg 	  return true;
   1523  1.1  mrg 	}
   1524  1.1  mrg       else if (HAVE_AS_TLS && unspec_num == UNSPEC_TLS_GD)
   1525  1.1  mrg 	{
   1526  1.1  mrg 	  emit_insn (gen_tls_gd_addhi (operands[0], const0_rtx,
   1527  1.1  mrg 				       XVECEXP (unspec, 0, 0)));
   1528  1.1  mrg 	  return true;
   1529  1.1  mrg 	}
   1530  1.1  mrg       else if (HAVE_AS_TLS && unspec_num == UNSPEC_TLS_IE)
   1531  1.1  mrg 	{
   1532  1.1  mrg 	  emit_insn (gen_tls_ie_addhi (operands[0], const0_rtx,
   1533  1.1  mrg 				       XVECEXP (unspec, 0, 0)));
   1534  1.1  mrg 	  return true;
   1535  1.1  mrg 	}
   1536  1.1  mrg       else if (HAVE_AS_TLS && unspec_num == UNSPEC_TLS_LE)
   1537  1.1  mrg 	{
   1538  1.1  mrg 	  emit_insn (gen_tls_le_addhi (operands[0], const0_rtx,
   1539  1.1  mrg 				       XVECEXP (unspec, 0, 0)));
   1540  1.1  mrg 	  return true;
   1541  1.1  mrg 	}
   1542  1.1  mrg     }
   1543  1.1  mrg 
   1544  1.1  mrg   /* Accept non-constants and valid constants unmodified.  */
   1545  1.1  mrg   if (!CONSTANT_P (operands[1])
   1546  1.1  mrg       || GET_CODE (operands[1]) == HIGH || move_operand (operands[1], mode))
   1547  1.1  mrg     return false;
   1548  1.1  mrg 
   1549  1.1  mrg   /* Split large integers.  */
   1550  1.1  mrg   if (GET_MODE_SIZE (mode) <= 4)
   1551  1.1  mrg     {
   1552  1.1  mrg       tilepro_expand_set_const32 (operands[0], operands[1]);
   1553  1.1  mrg       return true;
   1554  1.1  mrg     }
   1555  1.1  mrg 
   1556  1.1  mrg   return false;
   1557  1.1  mrg }
   1558  1.1  mrg 
   1559  1.1  mrg 
   1560  1.1  mrg /* Expand the "insv" pattern.  */
   1561  1.1  mrg void
   1562  1.1  mrg tilepro_expand_insv (rtx operands[4])
   1563  1.1  mrg {
   1564  1.1  mrg   rtx first_rtx = operands[2];
   1565  1.1  mrg   HOST_WIDE_INT first = INTVAL (first_rtx);
   1566  1.1  mrg   HOST_WIDE_INT width = INTVAL (operands[1]);
   1567  1.1  mrg   rtx v = operands[3];
   1568  1.1  mrg 
   1569  1.1  mrg   /* Shift the inserted bits into position.  */
   1570  1.1  mrg   if (first != 0)
   1571  1.1  mrg     {
   1572  1.1  mrg       if (CONST_INT_P (v))
   1573  1.1  mrg 	{
   1574  1.1  mrg 	  /* Shift the constant into mm position.  */
   1575  1.1  mrg 	  v = gen_int_si (INTVAL (v) << first);
   1576  1.1  mrg 	}
   1577  1.1  mrg       else
   1578  1.1  mrg 	{
   1579  1.1  mrg 	  /* Shift over the value to be inserted.  */
   1580  1.1  mrg 	  rtx tmp = gen_reg_rtx (SImode);
   1581  1.1  mrg 	  emit_insn (gen_ashlsi3 (tmp, v, first_rtx));
   1582  1.1  mrg 	  v = tmp;
   1583  1.1  mrg 	}
   1584  1.1  mrg     }
   1585  1.1  mrg 
   1586  1.1  mrg   /* Insert the shifted bits using an 'mm' insn.  */
   1587  1.1  mrg   emit_insn (gen_insn_mm (operands[0], v, operands[0], first_rtx,
   1588  1.1  mrg 			  GEN_INT (first + width - 1)));
   1589  1.1  mrg }
   1590  1.1  mrg 
   1591  1.1  mrg 
   1592  1.1  mrg /* Expand unaligned loads.  */
   1593  1.1  mrg void
   1594  1.1  mrg tilepro_expand_unaligned_load (rtx dest_reg, rtx mem, HOST_WIDE_INT bitsize,
   1595  1.1  mrg 			       HOST_WIDE_INT bit_offset, bool sign)
   1596  1.1  mrg {
   1597  1.1  mrg   machine_mode mode;
   1598  1.1  mrg   rtx addr_lo, addr_hi;
   1599  1.1  mrg   rtx mem_lo, mem_hi, hi;
   1600  1.1  mrg   rtx mema, wide_result;
   1601  1.1  mrg   int last_byte_offset;
   1602  1.1  mrg   HOST_WIDE_INT byte_offset = bit_offset / BITS_PER_UNIT;
   1603  1.1  mrg 
   1604  1.1  mrg   mode = GET_MODE (dest_reg);
   1605  1.1  mrg 
   1606  1.1  mrg   hi = gen_reg_rtx (mode);
   1607  1.1  mrg 
   1608  1.1  mrg   if (bitsize == 2 * BITS_PER_UNIT && (bit_offset % BITS_PER_UNIT) == 0)
   1609  1.1  mrg     {
   1610  1.1  mrg       rtx lo;
   1611  1.1  mrg 
   1612  1.1  mrg       /* When just loading a two byte value, we can load the two bytes
   1613  1.1  mrg          individually and combine them efficiently.  */
   1614  1.1  mrg 
   1615  1.1  mrg       mem_lo = adjust_address (mem, QImode, byte_offset);
   1616  1.1  mrg       mem_hi = adjust_address (mem, QImode, byte_offset + 1);
   1617  1.1  mrg 
   1618  1.1  mrg       lo = gen_reg_rtx (mode);
   1619  1.1  mrg       emit_insn (gen_zero_extendqisi2 (lo, mem_lo));
   1620  1.1  mrg 
   1621  1.1  mrg       if (sign)
   1622  1.1  mrg 	{
   1623  1.1  mrg 	  rtx tmp = gen_reg_rtx (mode);
   1624  1.1  mrg 
   1625  1.1  mrg 	  /* Do a signed load of the second byte then shift and OR it
   1626  1.1  mrg 	     in.  */
   1627  1.1  mrg 	  emit_insn (gen_extendqisi2 (gen_lowpart (SImode, hi), mem_hi));
   1628  1.1  mrg 	  emit_insn (gen_ashlsi3 (gen_lowpart (SImode, tmp),
   1629  1.1  mrg 				  gen_lowpart (SImode, hi), GEN_INT (8)));
   1630  1.1  mrg 	  emit_insn (gen_iorsi3 (gen_lowpart (SImode, dest_reg),
   1631  1.1  mrg 				 gen_lowpart (SImode, lo),
   1632  1.1  mrg 				 gen_lowpart (SImode, tmp)));
   1633  1.1  mrg 	}
   1634  1.1  mrg       else
   1635  1.1  mrg 	{
   1636  1.1  mrg 	  /* Do two unsigned loads and use intlb to interleave
   1637  1.1  mrg 	     them.  */
   1638  1.1  mrg 	  emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, hi), mem_hi));
   1639  1.1  mrg 	  emit_insn (gen_insn_intlb (gen_lowpart (SImode, dest_reg),
   1640  1.1  mrg 				     gen_lowpart (SImode, hi),
   1641  1.1  mrg 				     gen_lowpart (SImode, lo)));
   1642  1.1  mrg 	}
   1643  1.1  mrg 
   1644  1.1  mrg       return;
   1645  1.1  mrg     }
   1646  1.1  mrg 
   1647  1.1  mrg   mema = XEXP (mem, 0);
   1648  1.1  mrg 
   1649  1.1  mrg   /* AND addresses cannot be in any alias set, since they may
   1650  1.1  mrg      implicitly alias surrounding code.  Ideally we'd have some alias
   1651  1.1  mrg      set that covered all types except those with alignment 8 or
   1652  1.1  mrg      higher.  */
   1653  1.1  mrg   addr_lo = force_reg (Pmode, plus_constant (Pmode, mema, byte_offset));
   1654  1.1  mrg   mem_lo = change_address (mem, mode,
   1655  1.1  mrg 			   gen_rtx_AND (Pmode, addr_lo, GEN_INT (-4)));
   1656  1.1  mrg   set_mem_alias_set (mem_lo, 0);
   1657  1.1  mrg 
   1658  1.1  mrg   /* Load the high word at an address that will not fault if the low
   1659  1.1  mrg      address is aligned and at the very end of a page.  */
   1660  1.1  mrg   last_byte_offset = (bit_offset + bitsize - 1) / BITS_PER_UNIT;
   1661  1.1  mrg   addr_hi = force_reg (Pmode, plus_constant (Pmode, mema, last_byte_offset));
   1662  1.1  mrg   mem_hi = change_address (mem, mode,
   1663  1.1  mrg 			   gen_rtx_AND (Pmode, addr_hi, GEN_INT (-4)));
   1664  1.1  mrg   set_mem_alias_set (mem_hi, 0);
   1665  1.1  mrg 
   1666  1.1  mrg   if (bitsize == 32)
   1667  1.1  mrg     {
   1668  1.1  mrg       addr_lo = make_safe_from (addr_lo, dest_reg);
   1669  1.1  mrg       wide_result = dest_reg;
   1670  1.1  mrg     }
   1671  1.1  mrg   else
   1672  1.1  mrg     {
   1673  1.1  mrg       wide_result = gen_reg_rtx (mode);
   1674  1.1  mrg     }
   1675  1.1  mrg 
   1676  1.1  mrg   /* Load hi first in case dest_reg is used in mema.  */
   1677  1.1  mrg   emit_move_insn (hi, mem_hi);
   1678  1.1  mrg   emit_move_insn (wide_result, mem_lo);
   1679  1.1  mrg 
   1680  1.1  mrg   emit_insn (gen_insn_dword_align (gen_lowpart (SImode, wide_result),
   1681  1.1  mrg 				   gen_lowpart (SImode, wide_result),
   1682  1.1  mrg 				   gen_lowpart (SImode, hi), addr_lo));
   1683  1.1  mrg 
   1684  1.1  mrg   if (bitsize != 32)
   1685  1.1  mrg     {
   1686  1.1  mrg       rtx extracted =
   1687  1.1  mrg 	extract_bit_field (gen_lowpart (SImode, wide_result),
   1688  1.1  mrg 			   bitsize, bit_offset % BITS_PER_UNIT,
   1689  1.1  mrg 			   !sign, gen_lowpart (SImode, dest_reg),
   1690  1.1  mrg 			   SImode, SImode, false, NULL);
   1691  1.1  mrg 
   1692  1.1  mrg       if (extracted != dest_reg)
   1693  1.1  mrg 	emit_move_insn (dest_reg, gen_lowpart (SImode, extracted));
   1694  1.1  mrg     }
   1695  1.1  mrg }
   1696  1.1  mrg 
   1697  1.1  mrg 
   1698  1.1  mrg /* Expand unaligned stores.  */
   1699  1.1  mrg static void
   1700  1.1  mrg tilepro_expand_unaligned_store (rtx mem, rtx src, HOST_WIDE_INT bitsize,
   1701  1.1  mrg 				HOST_WIDE_INT bit_offset)
   1702  1.1  mrg {
   1703  1.1  mrg   HOST_WIDE_INT byte_offset = bit_offset / BITS_PER_UNIT;
   1704  1.1  mrg   HOST_WIDE_INT bytesize = bitsize / BITS_PER_UNIT;
   1705  1.1  mrg   HOST_WIDE_INT shift_amt;
   1706  1.1  mrg   HOST_WIDE_INT i;
   1707  1.1  mrg   rtx mem_addr;
   1708  1.1  mrg   rtx store_val;
   1709  1.1  mrg 
   1710  1.1  mrg   for (i = 0, shift_amt = 0; i < bytesize; i++, shift_amt += BITS_PER_UNIT)
   1711  1.1  mrg     {
   1712  1.1  mrg       mem_addr = adjust_address (mem, QImode, byte_offset + i);
   1713  1.1  mrg 
   1714  1.1  mrg       if (shift_amt)
   1715  1.1  mrg 	{
   1716  1.1  mrg 	  store_val = expand_simple_binop (SImode, LSHIFTRT,
   1717  1.1  mrg 					   gen_lowpart (SImode, src),
   1718  1.1  mrg 					   GEN_INT (shift_amt), NULL, 1,
   1719  1.1  mrg 					   OPTAB_LIB_WIDEN);
   1720  1.1  mrg 	  store_val = gen_lowpart (QImode, store_val);
   1721  1.1  mrg 	}
   1722  1.1  mrg       else
   1723  1.1  mrg 	{
   1724  1.1  mrg 	  store_val = gen_lowpart (QImode, src);
   1725  1.1  mrg 	}
   1726  1.1  mrg 
   1727  1.1  mrg       emit_move_insn (mem_addr, store_val);
   1728  1.1  mrg     }
   1729  1.1  mrg }
   1730  1.1  mrg 
   1731  1.1  mrg 
   1732  1.1  mrg /* Implement the movmisalign patterns.  One of the operands is a
   1733  1.1  mrg    memory that is not naturally aligned.  Emit instructions to load
   1734  1.1  mrg    it.  */
   1735  1.1  mrg void
   1736  1.1  mrg tilepro_expand_movmisalign (machine_mode mode, rtx *operands)
   1737  1.1  mrg {
   1738  1.1  mrg   if (MEM_P (operands[1]))
   1739  1.1  mrg     {
   1740  1.1  mrg       rtx tmp;
   1741  1.1  mrg 
   1742  1.1  mrg       if (register_operand (operands[0], mode))
   1743  1.1  mrg 	tmp = operands[0];
   1744  1.1  mrg       else
   1745  1.1  mrg 	tmp = gen_reg_rtx (mode);
   1746  1.1  mrg 
   1747  1.1  mrg       tilepro_expand_unaligned_load (tmp, operands[1],
   1748  1.1  mrg 				     GET_MODE_BITSIZE (mode), 0, true);
   1749  1.1  mrg 
   1750  1.1  mrg       if (tmp != operands[0])
   1751  1.1  mrg 	emit_move_insn (operands[0], tmp);
   1752  1.1  mrg     }
   1753  1.1  mrg   else if (MEM_P (operands[0]))
   1754  1.1  mrg     {
   1755  1.1  mrg       if (!reg_or_0_operand (operands[1], mode))
   1756  1.1  mrg 	operands[1] = force_reg (mode, operands[1]);
   1757  1.1  mrg 
   1758  1.1  mrg       tilepro_expand_unaligned_store (operands[0], operands[1],
   1759  1.1  mrg 				      GET_MODE_BITSIZE (mode), 0);
   1760  1.1  mrg     }
   1761  1.1  mrg   else
   1762  1.1  mrg     gcc_unreachable ();
   1763  1.1  mrg }
   1764  1.1  mrg 
   1765  1.1  mrg 
   1766  1.1  mrg /* Implement the addsi3 pattern.  */
   1767  1.1  mrg bool
   1768  1.1  mrg tilepro_expand_addsi (rtx op0, rtx op1, rtx op2)
   1769  1.1  mrg {
   1770  1.1  mrg   rtx temp;
   1771  1.1  mrg   HOST_WIDE_INT n;
   1772  1.1  mrg   HOST_WIDE_INT high;
   1773  1.1  mrg 
   1774  1.1  mrg   /* Skip anything that only takes one instruction.  */
   1775  1.1  mrg   if (add_operand (op2, SImode))
   1776  1.1  mrg     return false;
   1777  1.1  mrg 
   1778  1.1  mrg   /* We can only optimize ints here (it should be impossible to get
   1779  1.1  mrg      here with any other type, but it is harmless to check.  */
   1780  1.1  mrg   if (!CONST_INT_P (op2))
   1781  1.1  mrg     return false;
   1782  1.1  mrg 
   1783  1.1  mrg   temp = create_temp_reg_if_possible (SImode, op0);
   1784  1.1  mrg   n = INTVAL (op2);
   1785  1.1  mrg   high = (n + (n & 0x8000)) & ~0xffff;
   1786  1.1  mrg 
   1787  1.1  mrg   emit_move_insn (temp, gen_rtx_PLUS (SImode, op1, gen_int_si (high)));
   1788  1.1  mrg   emit_move_insn (op0, gen_rtx_PLUS (SImode, temp, gen_int_si (n - high)));
   1789  1.1  mrg 
   1790  1.1  mrg   return true;
   1791  1.1  mrg }
   1792  1.1  mrg 
   1793  1.1  mrg 
   1794  1.1  mrg /* Implement the allocate_stack pattern (alloca).  */
   1795  1.1  mrg void
   1796  1.1  mrg tilepro_allocate_stack (rtx op0, rtx op1)
   1797  1.1  mrg {
   1798  1.1  mrg   /* Technically the correct way to initialize chain_loc is with
   1799  1.1  mrg    * gen_frame_mem() instead of gen_rtx_MEM(), but gen_frame_mem()
   1800  1.1  mrg    * sets the alias_set to that of a frame reference.  Some of our
   1801  1.1  mrg    * tests rely on some unsafe assumption about when the chaining
   1802  1.1  mrg    * update is done, we need to be conservative about reordering the
   1803  1.1  mrg    * chaining instructions.
   1804  1.1  mrg    */
   1805  1.1  mrg   rtx fp_addr = gen_reg_rtx (Pmode);
   1806  1.1  mrg   rtx fp_value = gen_reg_rtx (Pmode);
   1807  1.1  mrg   rtx fp_loc;
   1808  1.1  mrg 
   1809  1.1  mrg   emit_move_insn (fp_addr, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   1810  1.1  mrg 					 GEN_INT (UNITS_PER_WORD)));
   1811  1.1  mrg 
   1812  1.1  mrg   fp_loc = gen_frame_mem (Pmode, fp_addr);
   1813  1.1  mrg 
   1814  1.1  mrg   emit_move_insn (fp_value, fp_loc);
   1815  1.1  mrg 
   1816  1.1  mrg   op1 = force_reg (Pmode, op1);
   1817  1.1  mrg 
   1818  1.1  mrg   emit_move_insn (stack_pointer_rtx,
   1819  1.1  mrg 		  gen_rtx_MINUS (Pmode, stack_pointer_rtx, op1));
   1820  1.1  mrg 
   1821  1.1  mrg   emit_move_insn (fp_addr, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   1822  1.1  mrg 					 GEN_INT (UNITS_PER_WORD)));
   1823  1.1  mrg 
   1824  1.1  mrg   fp_loc = gen_frame_mem (Pmode, fp_addr);
   1825  1.1  mrg 
   1826  1.1  mrg   emit_move_insn (fp_loc, fp_value);
   1827  1.1  mrg 
   1828  1.1  mrg   emit_move_insn (op0, virtual_stack_dynamic_rtx);
   1829  1.1  mrg }
   1830  1.1  mrg 
   1831  1.1  mrg 
   1833  1.1  mrg 
   1834  1.1  mrg /* Multiplies */
   1835  1.1  mrg 
   1836  1.1  mrg /* Returns the insn_code in ENTRY.  */
   1837  1.1  mrg static enum insn_code
   1838  1.1  mrg tilepro_multiply_get_opcode (const struct tilepro_multiply_insn_seq_entry
   1839  1.1  mrg 			     *entry)
   1840  1.1  mrg {
   1841  1.1  mrg   return tilepro_multiply_insn_seq_decode_opcode[entry->compressed_opcode];
   1842  1.1  mrg }
   1843  1.1  mrg 
   1844  1.1  mrg 
   1845  1.1  mrg /* Returns the length of the 'op' array.  */
   1846  1.1  mrg static int
   1847  1.1  mrg tilepro_multiply_get_num_ops (const struct tilepro_multiply_insn_seq *seq)
   1848  1.1  mrg {
   1849  1.1  mrg   /* The array either uses all of its allocated slots or is terminated
   1850  1.1  mrg      by a bogus opcode. Either way, the array size is the index of the
   1851  1.1  mrg      last valid opcode plus one.  */
   1852  1.1  mrg   int i;
   1853  1.1  mrg   for (i = tilepro_multiply_insn_seq_MAX_OPERATIONS - 1; i >= 0; i--)
   1854  1.1  mrg     if (tilepro_multiply_get_opcode (&seq->op[i]) != CODE_FOR_nothing)
   1855  1.1  mrg       return i + 1;
   1856  1.1  mrg 
   1857  1.1  mrg   /* An empty array is not allowed.  */
   1858  1.1  mrg   gcc_unreachable ();
   1859  1.1  mrg }
   1860  1.1  mrg 
   1861  1.1  mrg 
   1862  1.1  mrg /* We precompute a number of expression trees for multiplying by
   1863  1.1  mrg    constants.  This generates code for such an expression tree by
   1864  1.1  mrg    walking through the nodes in the tree (which are conveniently
   1865  1.1  mrg    pre-linearized) and emitting an instruction for each one.  */
   1866  1.1  mrg static void
   1867  1.1  mrg tilepro_expand_constant_multiply_given_sequence (rtx result, rtx src,
   1868  1.1  mrg 						 const struct
   1869  1.1  mrg 						 tilepro_multiply_insn_seq
   1870  1.1  mrg 						 *seq)
   1871  1.1  mrg {
   1872  1.1  mrg   int i;
   1873  1.1  mrg   int num_ops;
   1874  1.1  mrg 
   1875  1.1  mrg   /* Keep track of the subexpressions computed so far, so later
   1876  1.1  mrg      instructions can refer to them.  We seed the array with zero and
   1877  1.1  mrg      the value being multiplied.  */
   1878  1.1  mrg   int num_subexprs = 2;
   1879  1.1  mrg   rtx subexprs[tilepro_multiply_insn_seq_MAX_OPERATIONS + 2];
   1880  1.1  mrg   subexprs[0] = const0_rtx;
   1881  1.1  mrg   subexprs[1] = src;
   1882  1.1  mrg 
   1883  1.1  mrg   /* Determine how many instructions we are going to generate.  */
   1884  1.1  mrg   num_ops = tilepro_multiply_get_num_ops (seq);
   1885  1.1  mrg   gcc_assert (num_ops > 0
   1886  1.1  mrg 	      && num_ops <= tilepro_multiply_insn_seq_MAX_OPERATIONS);
   1887  1.1  mrg 
   1888  1.1  mrg   for (i = 0; i < num_ops; i++)
   1889  1.1  mrg     {
   1890  1.1  mrg       const struct tilepro_multiply_insn_seq_entry *entry = &seq->op[i];
   1891  1.1  mrg 
   1892  1.1  mrg       /* Figure out where to store the output of this instruction.  */
   1893  1.1  mrg       const bool is_last_op = (i + 1 == num_ops);
   1894  1.1  mrg       rtx out = is_last_op ? result : gen_reg_rtx (SImode);
   1895  1.1  mrg 
   1896  1.1  mrg       enum insn_code opcode = tilepro_multiply_get_opcode (entry);
   1897  1.1  mrg       if (opcode == CODE_FOR_ashlsi3)
   1898  1.1  mrg 	{
   1899  1.1  mrg 	  /* Handle shift by immediate. This is a special case because
   1900  1.1  mrg 	     the meaning of the second operand is a constant shift
   1901  1.1  mrg 	     count rather than an operand index.  */
   1902  1.1  mrg 
   1903  1.1  mrg 	  /* Make sure the shift count is in range. Zero should not
   1904  1.1  mrg 	     happen.  */
   1905  1.1  mrg 	  const int shift_count = entry->rhs;
   1906  1.1  mrg 	  gcc_assert (shift_count > 0 && shift_count < 32);
   1907  1.1  mrg 
   1908  1.1  mrg 	  /* Emit the actual instruction.  */
   1909  1.1  mrg 	  emit_insn (GEN_FCN (opcode)
   1910  1.1  mrg 		     (out, subexprs[entry->lhs],
   1911  1.1  mrg 		      gen_rtx_CONST_INT (SImode, shift_count)));
   1912  1.1  mrg 	}
   1913  1.1  mrg       else
   1914  1.1  mrg 	{
   1915  1.1  mrg 	  /* Handle a normal two-operand instruction, such as add or
   1916  1.1  mrg 	     s1a.  */
   1917  1.1  mrg 
   1918  1.1  mrg 	  /* Make sure we are referring to a previously computed
   1919  1.1  mrg 	     subexpression.  */
   1920  1.1  mrg 	  gcc_assert (entry->rhs < num_subexprs);
   1921  1.1  mrg 
   1922  1.1  mrg 	  /* Emit the actual instruction.  */
   1923  1.1  mrg 	  emit_insn (GEN_FCN (opcode)
   1924  1.1  mrg 		     (out, subexprs[entry->lhs], subexprs[entry->rhs]));
   1925  1.1  mrg 	}
   1926  1.1  mrg 
   1927  1.1  mrg       /* Record this subexpression for use by later expressions.  */
   1928  1.1  mrg       subexprs[num_subexprs++] = out;
   1929  1.1  mrg     }
   1930  1.1  mrg }
   1931  1.1  mrg 
   1932  1.1  mrg 
   1933  1.1  mrg /* bsearch helper function.  */
   1934  1.1  mrg static int
   1935  1.1  mrg tilepro_compare_multipliers (const void *key, const void *t)
   1936  1.1  mrg {
   1937  1.1  mrg   return *(const int *) key -
   1938  1.1  mrg     ((const struct tilepro_multiply_insn_seq *) t)->multiplier;
   1939  1.1  mrg }
   1940  1.1  mrg 
   1941  1.1  mrg 
   1942  1.1  mrg /* Returns the tilepro_multiply_insn_seq for multiplier, or NULL if
   1943  1.1  mrg    none exists.  */
   1944  1.1  mrg static const struct tilepro_multiply_insn_seq *
   1945  1.1  mrg tilepro_find_multiply_insn_seq_for_constant (int multiplier)
   1946  1.1  mrg {
   1947  1.1  mrg   return ((const struct tilepro_multiply_insn_seq *)
   1948  1.1  mrg 	  bsearch (&multiplier, tilepro_multiply_insn_seq_table,
   1949  1.1  mrg 		   tilepro_multiply_insn_seq_table_size,
   1950  1.1  mrg 		   sizeof tilepro_multiply_insn_seq_table[0],
   1951  1.1  mrg 		   tilepro_compare_multipliers));
   1952  1.1  mrg }
   1953  1.1  mrg 
   1954  1.1  mrg 
   1955  1.1  mrg /* Try to a expand constant multiply in SImode by looking it up in a
   1956  1.1  mrg    precompiled table.  OP0 is the result operand, OP1 is the source
   1957  1.1  mrg    operand, and MULTIPLIER is the value of the constant.  Return true
   1958  1.1  mrg    if it succeeds.  */
   1959  1.1  mrg static bool
   1960  1.1  mrg tilepro_expand_const_mulsi (rtx op0, rtx op1, int multiplier)
   1961  1.1  mrg {
   1962  1.1  mrg   /* See if we have precomputed an efficient way to multiply by this
   1963  1.1  mrg      constant.  */
   1964  1.1  mrg   const struct tilepro_multiply_insn_seq *seq =
   1965  1.1  mrg     tilepro_find_multiply_insn_seq_for_constant (multiplier);
   1966  1.1  mrg   if (seq != NULL)
   1967  1.1  mrg     {
   1968  1.1  mrg       tilepro_expand_constant_multiply_given_sequence (op0, op1, seq);
   1969  1.1  mrg       return true;
   1970  1.1  mrg     }
   1971  1.1  mrg   else
   1972  1.1  mrg     return false;
   1973  1.1  mrg }
   1974  1.1  mrg 
   1975  1.1  mrg 
   1976  1.1  mrg /* Expand the mulsi pattern.  */
   1977  1.1  mrg bool
   1978  1.1  mrg tilepro_expand_mulsi (rtx op0, rtx op1, rtx op2)
   1979  1.1  mrg {
   1980  1.1  mrg   if (CONST_INT_P (op2))
   1981  1.1  mrg     {
   1982  1.1  mrg       HOST_WIDE_INT n = trunc_int_for_mode (INTVAL (op2), SImode);
   1983  1.1  mrg       return tilepro_expand_const_mulsi (op0, op1, n);
   1984  1.1  mrg     }
   1985  1.1  mrg   return false;
   1986  1.1  mrg }
   1987  1.1  mrg 
   1988  1.1  mrg 
   1989  1.1  mrg /* Expand a high multiply pattern in SImode.  RESULT, OP1, OP2 are the
   1990  1.1  mrg    operands, and SIGN is true if it's a signed multiply, and false if
   1991  1.1  mrg    it's an unsigned multiply.  */
   1992  1.1  mrg static void
   1993  1.1  mrg tilepro_expand_high_multiply (rtx result, rtx op1, rtx op2, bool sign)
   1994  1.1  mrg {
   1995  1.1  mrg   rtx tmp0 = gen_reg_rtx (SImode);
   1996  1.1  mrg   rtx tmp1 = gen_reg_rtx (SImode);
   1997  1.1  mrg   rtx tmp2 = gen_reg_rtx (SImode);
   1998  1.1  mrg   rtx tmp3 = gen_reg_rtx (SImode);
   1999  1.1  mrg   rtx tmp4 = gen_reg_rtx (SImode);
   2000  1.1  mrg   rtx tmp5 = gen_reg_rtx (SImode);
   2001  1.1  mrg   rtx tmp6 = gen_reg_rtx (SImode);
   2002  1.1  mrg   rtx tmp7 = gen_reg_rtx (SImode);
   2003  1.1  mrg   rtx tmp8 = gen_reg_rtx (SImode);
   2004  1.1  mrg   rtx tmp9 = gen_reg_rtx (SImode);
   2005  1.1  mrg   rtx tmp10 = gen_reg_rtx (SImode);
   2006  1.1  mrg   rtx tmp11 = gen_reg_rtx (SImode);
   2007  1.1  mrg   rtx tmp12 = gen_reg_rtx (SImode);
   2008  1.1  mrg   rtx tmp13 = gen_reg_rtx (SImode);
   2009  1.1  mrg   rtx result_lo = gen_reg_rtx (SImode);
   2010  1.1  mrg 
   2011  1.1  mrg   if (sign)
   2012  1.1  mrg     {
   2013  1.1  mrg       emit_insn (gen_insn_mulhl_su (tmp0, op1, op2));
   2014  1.1  mrg       emit_insn (gen_insn_mulhl_su (tmp1, op2, op1));
   2015  1.1  mrg       emit_insn (gen_insn_mulll_uu (tmp2, op1, op2));
   2016  1.1  mrg       emit_insn (gen_insn_mulhh_ss (tmp3, op1, op2));
   2017  1.1  mrg     }
   2018  1.1  mrg   else
   2019  1.1  mrg     {
   2020  1.1  mrg       emit_insn (gen_insn_mulhl_uu (tmp0, op1, op2));
   2021  1.1  mrg       emit_insn (gen_insn_mulhl_uu (tmp1, op2, op1));
   2022  1.1  mrg       emit_insn (gen_insn_mulll_uu (tmp2, op1, op2));
   2023  1.1  mrg       emit_insn (gen_insn_mulhh_uu (tmp3, op1, op2));
   2024  1.1  mrg     }
   2025  1.1  mrg 
   2026  1.1  mrg   emit_move_insn (tmp4, (gen_rtx_ASHIFT (SImode, tmp0, GEN_INT (16))));
   2027  1.1  mrg 
   2028  1.1  mrg   emit_move_insn (tmp5, (gen_rtx_ASHIFT (SImode, tmp1, GEN_INT (16))));
   2029  1.1  mrg 
   2030  1.1  mrg   emit_move_insn (tmp6, (gen_rtx_PLUS (SImode, tmp4, tmp5)));
   2031  1.1  mrg   emit_move_insn (result_lo, (gen_rtx_PLUS (SImode, tmp2, tmp6)));
   2032  1.1  mrg 
   2033  1.1  mrg   emit_move_insn (tmp7, gen_rtx_LTU (SImode, tmp6, tmp4));
   2034  1.1  mrg   emit_move_insn (tmp8, gen_rtx_LTU (SImode, result_lo, tmp2));
   2035  1.1  mrg 
   2036  1.1  mrg   if (sign)
   2037  1.1  mrg     {
   2038  1.1  mrg       emit_move_insn (tmp9, (gen_rtx_ASHIFTRT (SImode, tmp0, GEN_INT (16))));
   2039  1.1  mrg       emit_move_insn (tmp10, (gen_rtx_ASHIFTRT (SImode, tmp1, GEN_INT (16))));
   2040  1.1  mrg     }
   2041  1.1  mrg   else
   2042  1.1  mrg     {
   2043  1.1  mrg       emit_move_insn (tmp9, (gen_rtx_LSHIFTRT (SImode, tmp0, GEN_INT (16))));
   2044  1.1  mrg       emit_move_insn (tmp10, (gen_rtx_LSHIFTRT (SImode, tmp1, GEN_INT (16))));
   2045  1.1  mrg     }
   2046  1.1  mrg 
   2047  1.1  mrg   emit_move_insn (tmp11, (gen_rtx_PLUS (SImode, tmp3, tmp7)));
   2048  1.1  mrg   emit_move_insn (tmp12, (gen_rtx_PLUS (SImode, tmp8, tmp9)));
   2049  1.1  mrg   emit_move_insn (tmp13, (gen_rtx_PLUS (SImode, tmp11, tmp12)));
   2050  1.1  mrg   emit_move_insn (result, (gen_rtx_PLUS (SImode, tmp13, tmp10)));
   2051  1.1  mrg }
   2052  1.1  mrg 
   2053  1.1  mrg 
   2054  1.1  mrg /* Implement smulsi3_highpart.  */
   2055  1.1  mrg void
   2056  1.1  mrg tilepro_expand_smulsi3_highpart (rtx op0, rtx op1, rtx op2)
   2057  1.1  mrg {
   2058  1.1  mrg   tilepro_expand_high_multiply (op0, op1, op2, true);
   2059  1.1  mrg }
   2060  1.1  mrg 
   2061  1.1  mrg 
   2062  1.1  mrg /* Implement umulsi3_highpart.  */
   2063  1.1  mrg void
   2064  1.1  mrg tilepro_expand_umulsi3_highpart (rtx op0, rtx op1, rtx op2)
   2065  1.1  mrg {
   2066  1.1  mrg   tilepro_expand_high_multiply (op0, op1, op2, false);
   2067  1.1  mrg }
   2068  1.1  mrg 
   2069  1.1  mrg 
   2071  1.1  mrg 
   2072  1.1  mrg /* Compare and branches  */
   2073  1.1  mrg 
   2074  1.1  mrg /* Helper function to handle DImode for tilepro_emit_setcc_internal.  */
   2075  1.1  mrg static bool
   2076  1.1  mrg tilepro_emit_setcc_internal_di (rtx res, enum rtx_code code, rtx op0, rtx op1)
   2077  1.1  mrg {
   2078  1.1  mrg   rtx operands[2], lo_half[2], hi_half[2];
   2079  1.1  mrg   rtx tmp, tmp0, tmp1, tmp2;
   2080  1.1  mrg   bool swap = false;
   2081  1.1  mrg 
   2082  1.1  mrg   /* Reduce the number of cases we need to handle by reversing the
   2083  1.1  mrg      operands.  */
   2084  1.1  mrg   switch (code)
   2085  1.1  mrg     {
   2086  1.1  mrg     case EQ:
   2087  1.1  mrg     case NE:
   2088  1.1  mrg     case LE:
   2089  1.1  mrg     case LT:
   2090  1.1  mrg     case LEU:
   2091  1.1  mrg     case LTU:
   2092  1.1  mrg       /* We handle these compares directly.  */
   2093  1.1  mrg       break;
   2094  1.1  mrg 
   2095  1.1  mrg     case GE:
   2096  1.1  mrg     case GT:
   2097  1.1  mrg     case GEU:
   2098  1.1  mrg     case GTU:
   2099  1.1  mrg       /* Reverse the operands.  */
   2100  1.1  mrg       swap = true;
   2101  1.1  mrg       break;
   2102  1.1  mrg 
   2103  1.1  mrg     default:
   2104  1.1  mrg       /* We should not have called this with any other code.  */
   2105  1.1  mrg       gcc_unreachable ();
   2106  1.1  mrg     }
   2107  1.1  mrg 
   2108  1.1  mrg   if (swap)
   2109  1.1  mrg     {
   2110  1.1  mrg       code = swap_condition (code);
   2111  1.1  mrg       tmp = op0, op0 = op1, op1 = tmp;
   2112  1.1  mrg     }
   2113  1.1  mrg 
   2114  1.1  mrg   operands[0] = op0;
   2115  1.1  mrg   operands[1] = op1;
   2116  1.1  mrg 
   2117  1.1  mrg   split_di (operands, 2, lo_half, hi_half);
   2118  1.1  mrg 
   2119  1.1  mrg   if (!reg_or_0_operand (lo_half[0], SImode))
   2120  1.1  mrg     lo_half[0] = force_reg (SImode, lo_half[0]);
   2121  1.1  mrg 
   2122  1.1  mrg   if (!reg_or_0_operand (hi_half[0], SImode))
   2123  1.1  mrg     hi_half[0] = force_reg (SImode, hi_half[0]);
   2124  1.1  mrg 
   2125  1.1  mrg   if (!CONST_INT_P (lo_half[1]) && !register_operand (lo_half[1], SImode))
   2126  1.1  mrg     lo_half[1] = force_reg (SImode, lo_half[1]);
   2127  1.1  mrg 
   2128  1.1  mrg   if (!CONST_INT_P (hi_half[1]) && !register_operand (hi_half[1], SImode))
   2129  1.1  mrg     hi_half[1] = force_reg (SImode, hi_half[1]);
   2130  1.1  mrg 
   2131  1.1  mrg   tmp0 = gen_reg_rtx (SImode);
   2132  1.1  mrg   tmp1 = gen_reg_rtx (SImode);
   2133  1.1  mrg   tmp2 = gen_reg_rtx (SImode);
   2134  1.1  mrg 
   2135  1.1  mrg   switch (code)
   2136  1.1  mrg     {
   2137  1.1  mrg     case EQ:
   2138  1.1  mrg       emit_insn (gen_insn_seq (tmp0, lo_half[0], lo_half[1]));
   2139  1.1  mrg       emit_insn (gen_insn_seq (tmp1, hi_half[0], hi_half[1]));
   2140  1.1  mrg       emit_insn (gen_andsi3 (res, tmp0, tmp1));
   2141  1.1  mrg       return true;
   2142  1.1  mrg     case NE:
   2143  1.1  mrg       emit_insn (gen_insn_sne (tmp0, lo_half[0], lo_half[1]));
   2144  1.1  mrg       emit_insn (gen_insn_sne (tmp1, hi_half[0], hi_half[1]));
   2145  1.1  mrg       emit_insn (gen_iorsi3 (res, tmp0, tmp1));
   2146  1.1  mrg       return true;
   2147  1.1  mrg     case LE:
   2148  1.1  mrg       emit_insn (gen_insn_slte (tmp0, hi_half[0], hi_half[1]));
   2149  1.1  mrg       emit_insn (gen_insn_seq (tmp1, hi_half[0], hi_half[1]));
   2150  1.1  mrg       emit_insn (gen_insn_slte_u (tmp2, lo_half[0], lo_half[1]));
   2151  1.1  mrg       emit_insn (gen_insn_mvnz (res, tmp0, tmp1, tmp2));
   2152  1.1  mrg       return true;
   2153  1.1  mrg     case LT:
   2154  1.1  mrg       if (operands[1] == const0_rtx)
   2155  1.1  mrg 	{
   2156  1.1  mrg 	  emit_insn (gen_lshrsi3 (res, hi_half[0], GEN_INT (31)));
   2157  1.1  mrg 	  return true;
   2158  1.1  mrg 	}
   2159  1.1  mrg       else
   2160  1.1  mrg 	{
   2161  1.1  mrg 	  emit_insn (gen_insn_slt (tmp0, hi_half[0], hi_half[1]));
   2162  1.1  mrg 	  emit_insn (gen_insn_seq (tmp1, hi_half[0], hi_half[1]));
   2163  1.1  mrg 	  emit_insn (gen_insn_slt_u (tmp2, lo_half[0], lo_half[1]));
   2164  1.1  mrg 	  emit_insn (gen_insn_mvnz (res, tmp0, tmp1, tmp2));
   2165  1.1  mrg 	}
   2166  1.1  mrg       return true;
   2167  1.1  mrg     case LEU:
   2168  1.1  mrg       emit_insn (gen_insn_slte_u (tmp0, hi_half[0], hi_half[1]));
   2169  1.1  mrg       emit_insn (gen_insn_seq (tmp1, hi_half[0], hi_half[1]));
   2170  1.1  mrg       emit_insn (gen_insn_slte_u (tmp2, lo_half[0], lo_half[1]));
   2171  1.1  mrg       emit_insn (gen_insn_mvnz (res, tmp0, tmp1, tmp2));
   2172  1.1  mrg       return true;
   2173  1.1  mrg     case LTU:
   2174  1.1  mrg       emit_insn (gen_insn_slt_u (tmp0, hi_half[0], hi_half[1]));
   2175  1.1  mrg       emit_insn (gen_insn_seq (tmp1, hi_half[0], hi_half[1]));
   2176  1.1  mrg       emit_insn (gen_insn_slt_u (tmp2, lo_half[0], lo_half[1]));
   2177  1.1  mrg       emit_insn (gen_insn_mvnz (res, tmp0, tmp1, tmp2));
   2178  1.1  mrg       return true;
   2179  1.1  mrg     default:
   2180  1.1  mrg       gcc_unreachable ();
   2181  1.1  mrg     }
   2182  1.1  mrg 
   2183  1.1  mrg   return false;
   2184  1.1  mrg }
   2185  1.1  mrg 
   2186  1.1  mrg 
   2187  1.1  mrg /* Certain simplifications can be done to make invalid setcc
   2188  1.1  mrg    operations valid.  Return the final comparison, or NULL if we can't
   2189  1.1  mrg    work.  */
   2190  1.1  mrg static bool
   2191  1.1  mrg tilepro_emit_setcc_internal (rtx res, enum rtx_code code, rtx op0, rtx op1,
   2192  1.1  mrg 			     machine_mode cmp_mode)
   2193  1.1  mrg {
   2194  1.1  mrg   rtx tmp;
   2195  1.1  mrg   bool swap = false;
   2196  1.1  mrg 
   2197  1.1  mrg   if (cmp_mode == DImode)
   2198  1.1  mrg     {
   2199  1.1  mrg       return tilepro_emit_setcc_internal_di (res, code, op0, op1);
   2200  1.1  mrg     }
   2201  1.1  mrg 
   2202  1.1  mrg   /* The general case: fold the comparison code to the types of
   2203  1.1  mrg      compares that we have, choosing the branch as necessary.  */
   2204  1.1  mrg 
   2205  1.1  mrg   switch (code)
   2206  1.1  mrg     {
   2207  1.1  mrg     case EQ:
   2208  1.1  mrg     case NE:
   2209  1.1  mrg     case LE:
   2210  1.1  mrg     case LT:
   2211  1.1  mrg     case LEU:
   2212  1.1  mrg     case LTU:
   2213  1.1  mrg       /* We have these compares.  */
   2214  1.1  mrg       break;
   2215  1.1  mrg 
   2216  1.1  mrg     case GE:
   2217  1.1  mrg     case GT:
   2218  1.1  mrg     case GEU:
   2219  1.1  mrg     case GTU:
   2220  1.1  mrg       /* We do not have these compares, so we reverse the
   2221  1.1  mrg          operands.  */
   2222  1.1  mrg       swap = true;
   2223  1.1  mrg       break;
   2224  1.1  mrg 
   2225  1.1  mrg     default:
   2226  1.1  mrg       /* We should not have called this with any other code.  */
   2227  1.1  mrg       gcc_unreachable ();
   2228  1.1  mrg     }
   2229  1.1  mrg 
   2230  1.1  mrg   if (swap)
   2231  1.1  mrg     {
   2232  1.1  mrg       code = swap_condition (code);
   2233  1.1  mrg       tmp = op0, op0 = op1, op1 = tmp;
   2234  1.1  mrg     }
   2235  1.1  mrg 
   2236  1.1  mrg   if (!reg_or_0_operand (op0, SImode))
   2237  1.1  mrg     op0 = force_reg (SImode, op0);
   2238  1.1  mrg 
   2239  1.1  mrg   if (!CONST_INT_P (op1) && !register_operand (op1, SImode))
   2240  1.1  mrg     op1 = force_reg (SImode, op1);
   2241  1.1  mrg 
   2242  1.1  mrg   /* Return the setcc comparison.  */
   2243  1.1  mrg   emit_insn (gen_rtx_SET (res, gen_rtx_fmt_ee (code, SImode, op0, op1)));
   2244  1.1  mrg 
   2245  1.1  mrg   return true;
   2246  1.1  mrg }
   2247  1.1  mrg 
   2248  1.1  mrg 
   2249  1.1  mrg /* Implement cstore patterns.  */
   2250  1.1  mrg bool
   2251  1.1  mrg tilepro_emit_setcc (rtx operands[], machine_mode cmp_mode)
   2252  1.1  mrg {
   2253  1.1  mrg   return
   2254  1.1  mrg     tilepro_emit_setcc_internal (operands[0], GET_CODE (operands[1]),
   2255  1.1  mrg 				 operands[2], operands[3], cmp_mode);
   2256  1.1  mrg }
   2257  1.1  mrg 
   2258  1.1  mrg 
   2259  1.1  mrg /* Return whether CODE is a signed comparison.  */
   2260  1.1  mrg static bool
   2261  1.1  mrg signed_compare_p (enum rtx_code code)
   2262  1.1  mrg {
   2263  1.1  mrg   return (code == EQ || code == NE || code == LT || code == LE
   2264  1.1  mrg 	  || code == GT || code == GE);
   2265  1.1  mrg }
   2266  1.1  mrg 
   2267  1.1  mrg 
   2268  1.1  mrg /* Generate the comparison for an SImode conditional branch.  */
   2269  1.1  mrg static rtx
   2270  1.1  mrg tilepro_emit_cc_test (enum rtx_code code, rtx op0, rtx op1,
   2271  1.1  mrg 		      machine_mode cmp_mode, bool eq_ne_only)
   2272  1.1  mrg {
   2273  1.1  mrg   enum rtx_code branch_code;
   2274  1.1  mrg   rtx temp;
   2275  1.1  mrg 
   2276  1.1  mrg   /* Check for a compare against zero using a comparison we can do
   2277  1.1  mrg      directly.  */
   2278  1.1  mrg   if (cmp_mode != DImode
   2279  1.1  mrg       && op1 == const0_rtx
   2280  1.1  mrg       && (code == EQ || code == NE
   2281  1.1  mrg 	  || (!eq_ne_only && signed_compare_p (code))))
   2282  1.1  mrg     {
   2283  1.1  mrg       op0 = force_reg (SImode, op0);
   2284  1.1  mrg       return gen_rtx_fmt_ee (code, VOIDmode, op0, const0_rtx);
   2285  1.1  mrg     }
   2286  1.1  mrg 
   2287  1.1  mrg   /* The general case: fold the comparison code to the types of
   2288  1.1  mrg      compares that we have, choosing the branch as necessary.  */
   2289  1.1  mrg   switch (code)
   2290  1.1  mrg     {
   2291  1.1  mrg     case EQ:
   2292  1.1  mrg     case LE:
   2293  1.1  mrg     case LT:
   2294  1.1  mrg     case LEU:
   2295  1.1  mrg     case LTU:
   2296  1.1  mrg       /* We have these compares.  */
   2297  1.1  mrg       branch_code = NE;
   2298  1.1  mrg       break;
   2299  1.1  mrg 
   2300  1.1  mrg     case NE:
   2301  1.1  mrg     case GE:
   2302  1.1  mrg     case GT:
   2303  1.1  mrg     case GEU:
   2304  1.1  mrg     case GTU:
   2305  1.1  mrg       /* These must be reversed (except NE, but let's
   2306  1.1  mrg          canonicalize).  */
   2307  1.1  mrg       code = reverse_condition (code);
   2308  1.1  mrg       branch_code = EQ;
   2309  1.1  mrg       break;
   2310  1.1  mrg 
   2311  1.1  mrg     default:
   2312  1.1  mrg       gcc_unreachable ();
   2313  1.1  mrg     }
   2314  1.1  mrg 
   2315  1.1  mrg   if (cmp_mode != DImode
   2316  1.1  mrg       && CONST_INT_P (op1) && (!satisfies_constraint_I (op1) || code == LEU))
   2317  1.1  mrg     {
   2318  1.1  mrg       HOST_WIDE_INT n = trunc_int_for_mode (INTVAL (op1), SImode);
   2319  1.1  mrg 
   2320  1.1  mrg       switch (code)
   2321  1.1  mrg 	{
   2322  1.1  mrg 	case EQ:
   2323  1.1  mrg 	  /* Subtract off the value we want to compare against and see
   2324  1.1  mrg 	     if we get zero.  This is cheaper than creating a constant
   2325  1.1  mrg 	     in a register. Except that subtracting -128 is more
   2326  1.1  mrg 	     expensive than seqi to -128, so we leave that alone.  */
   2327  1.1  mrg 	  /* ??? Don't do this when comparing against symbols,
   2328  1.1  mrg 	     otherwise we'll reduce (&x == 0x1234) to (&x-0x1234 ==
   2329  1.1  mrg 	     0), which will be declared false out of hand (at least
   2330  1.1  mrg 	     for non-weak).  */
   2331  1.1  mrg 	  if (!(symbolic_operand (op0, VOIDmode)
   2332  1.1  mrg 		|| (REG_P (op0) && REG_POINTER (op0))))
   2333  1.1  mrg 	    {
   2334  1.1  mrg 	      /* To compare against MIN_INT, we add MIN_INT and check
   2335  1.1  mrg 	         for 0.  */
   2336  1.1  mrg 	      HOST_WIDE_INT add;
   2337  1.1  mrg 	      if (n != -2147483647 - 1)
   2338  1.1  mrg 		add = -n;
   2339  1.1  mrg 	      else
   2340  1.1  mrg 		add = n;
   2341  1.1  mrg 
   2342  1.1  mrg 	      op0 = force_reg (SImode, op0);
   2343  1.1  mrg 	      temp = gen_reg_rtx (SImode);
   2344  1.1  mrg 	      emit_insn (gen_addsi3 (temp, op0, gen_int_si (add)));
   2345  1.1  mrg 	      return gen_rtx_fmt_ee (reverse_condition (branch_code),
   2346  1.1  mrg 				     VOIDmode, temp, const0_rtx);
   2347  1.1  mrg 	    }
   2348  1.1  mrg 	  break;
   2349  1.1  mrg 
   2350  1.1  mrg 	case LEU:
   2351  1.1  mrg 	  if (n == -1)
   2352  1.1  mrg 	    break;
   2353  1.1  mrg 	  /* FALLTHRU */
   2354  1.1  mrg 
   2355  1.1  mrg 	case LTU:
   2356  1.1  mrg 	  /* Change ((unsigned)x < 0x1000) into !((unsigned)x >> 12),
   2357  1.1  mrg 	     etc.  */
   2358  1.1  mrg 	  {
   2359  1.1  mrg 	    int first = exact_log2 (code == LTU ? n : n + 1);
   2360  1.1  mrg 	    if (first != -1)
   2361  1.1  mrg 	      {
   2362  1.1  mrg 		op0 = force_reg (SImode, op0);
   2363  1.1  mrg 		temp = gen_reg_rtx (SImode);
   2364  1.1  mrg 		emit_move_insn (temp,
   2365  1.1  mrg 				gen_rtx_LSHIFTRT (SImode, op0,
   2366  1.1  mrg 						  gen_int_si (first)));
   2367  1.1  mrg 		return gen_rtx_fmt_ee (reverse_condition (branch_code),
   2368  1.1  mrg 				       VOIDmode, temp, const0_rtx);
   2369  1.1  mrg 	      }
   2370  1.1  mrg 	  }
   2371  1.1  mrg 	  break;
   2372  1.1  mrg 
   2373  1.1  mrg 	default:
   2374  1.1  mrg 	  break;
   2375  1.1  mrg 	}
   2376  1.1  mrg     }
   2377  1.1  mrg 
   2378  1.1  mrg   /* Compute a flag saying whether we should branch.  */
   2379  1.1  mrg   temp = gen_reg_rtx (SImode);
   2380  1.1  mrg   tilepro_emit_setcc_internal (temp, code, op0, op1, cmp_mode);
   2381  1.1  mrg 
   2382  1.1  mrg   /* Return the branch comparison.  */
   2383  1.1  mrg   return gen_rtx_fmt_ee (branch_code, VOIDmode, temp, const0_rtx);
   2384  1.1  mrg }
   2385  1.1  mrg 
   2386  1.1  mrg 
   2387  1.1  mrg /* Generate the comparison for a conditional branch.  */
   2388  1.1  mrg void
   2389  1.1  mrg tilepro_emit_conditional_branch (rtx operands[], machine_mode cmp_mode)
   2390  1.1  mrg {
   2391  1.1  mrg   rtx cmp_rtx =
   2392  1.1  mrg     tilepro_emit_cc_test (GET_CODE (operands[0]), operands[1], operands[2],
   2393  1.1  mrg 			  cmp_mode, false);
   2394  1.1  mrg   rtx branch_rtx = gen_rtx_SET (pc_rtx,
   2395  1.1  mrg 				gen_rtx_IF_THEN_ELSE (VOIDmode, cmp_rtx,
   2396  1.1  mrg 						      gen_rtx_LABEL_REF
   2397  1.1  mrg 						      (VOIDmode,
   2398  1.1  mrg 						       operands[3]),
   2399  1.1  mrg 						      pc_rtx));
   2400  1.1  mrg   emit_jump_insn (branch_rtx);
   2401  1.1  mrg }
   2402  1.1  mrg 
   2403  1.1  mrg 
   2404  1.1  mrg /* Implement the movsicc pattern.  */
   2405  1.1  mrg rtx
   2406  1.1  mrg tilepro_emit_conditional_move (rtx cmp)
   2407  1.1  mrg {
   2408  1.1  mrg   return
   2409  1.1  mrg     tilepro_emit_cc_test (GET_CODE (cmp), XEXP (cmp, 0), XEXP (cmp, 1),
   2410  1.1  mrg 			  GET_MODE (XEXP (cmp, 0)), true);
   2411  1.1  mrg }
   2412  1.1  mrg 
   2413  1.1  mrg 
   2414  1.1  mrg /* Return true if INSN is annotated with a REG_BR_PROB note that
   2415  1.1  mrg    indicates it's a branch that's predicted taken.  */
   2416  1.1  mrg static bool
   2417  1.1  mrg cbranch_predicted_p (rtx_insn *insn)
   2418  1.1  mrg {
   2419  1.1  mrg   rtx x = find_reg_note (insn, REG_BR_PROB, 0);
   2420  1.1  mrg 
   2421  1.1  mrg   if (x)
   2422  1.1  mrg     {
   2423  1.1  mrg       return profile_probability::from_reg_br_prob_note (XINT (x, 0))
   2424  1.1  mrg 	     >= profile_probability::even ();
   2425  1.1  mrg     }
   2426  1.1  mrg 
   2427  1.1  mrg   return false;
   2428  1.1  mrg }
   2429  1.1  mrg 
   2430  1.1  mrg 
   2431  1.1  mrg /* Output assembly code for a specific branch instruction, appending
   2432  1.1  mrg    the branch prediction flag to the opcode if appropriate.  */
   2433  1.1  mrg static const char *
   2434  1.1  mrg tilepro_output_simple_cbranch_with_opcode (rtx_insn *insn, const char *opcode,
   2435  1.1  mrg 					   int regop, bool netreg_p,
   2436  1.1  mrg 					   bool reverse_predicted)
   2437  1.1  mrg {
   2438  1.1  mrg   static char buf[64];
   2439  1.1  mrg   sprintf (buf, "%s%s\t%%%c%d, %%l0", opcode,
   2440  1.1  mrg 	   (cbranch_predicted_p (insn) ^ reverse_predicted) ? "t" : "",
   2441  1.1  mrg 	   netreg_p ? 'N' : 'r', regop);
   2442  1.1  mrg   return buf;
   2443  1.1  mrg }
   2444  1.1  mrg 
   2445  1.1  mrg 
   2446  1.1  mrg /* Output assembly code for a specific branch instruction, appending
   2447  1.1  mrg    the branch prediction flag to the opcode if appropriate.  */
   2448  1.1  mrg const char *
   2449  1.1  mrg tilepro_output_cbranch_with_opcode (rtx_insn *insn, rtx *operands,
   2450  1.1  mrg 				    const char *opcode,
   2451  1.1  mrg 				    const char *rev_opcode,
   2452  1.1  mrg 				    int regop, bool netreg_p)
   2453  1.1  mrg {
   2454  1.1  mrg   const char *branch_if_false;
   2455  1.1  mrg   rtx taken, not_taken;
   2456  1.1  mrg   bool is_simple_branch;
   2457  1.1  mrg 
   2458  1.1  mrg   gcc_assert (LABEL_P (operands[0]));
   2459  1.1  mrg 
   2460  1.1  mrg   is_simple_branch = true;
   2461  1.1  mrg   if (INSN_ADDRESSES_SET_P ())
   2462  1.1  mrg     {
   2463  1.1  mrg       int from_addr = INSN_ADDRESSES (INSN_UID (insn));
   2464  1.1  mrg       int to_addr = INSN_ADDRESSES (INSN_UID (operands[0]));
   2465  1.1  mrg       int delta = to_addr - from_addr;
   2466  1.1  mrg       is_simple_branch = IN_RANGE (delta, -524288, 524280);
   2467  1.1  mrg     }
   2468  1.1  mrg 
   2469  1.1  mrg   if (is_simple_branch)
   2470  1.1  mrg     {
   2471  1.1  mrg       /* Just a simple conditional branch.  */
   2472  1.1  mrg       return
   2473  1.1  mrg 	tilepro_output_simple_cbranch_with_opcode (insn, opcode, regop,
   2474  1.1  mrg 						   netreg_p, false);
   2475  1.1  mrg     }
   2476  1.1  mrg 
   2477  1.1  mrg   /* Generate a reversed branch around a direct jump.  This fallback
   2478  1.1  mrg      does not use branch-likely instructions.  */
   2479  1.1  mrg   not_taken = gen_label_rtx ();
   2480  1.1  mrg   taken = operands[0];
   2481  1.1  mrg 
   2482  1.1  mrg   /* Generate the reversed branch to NOT_TAKEN.  */
   2483  1.1  mrg   operands[0] = not_taken;
   2484  1.1  mrg   branch_if_false =
   2485  1.1  mrg     tilepro_output_simple_cbranch_with_opcode (insn, rev_opcode, regop,
   2486  1.1  mrg 					       netreg_p, true);
   2487  1.1  mrg   output_asm_insn (branch_if_false, operands);
   2488  1.1  mrg 
   2489  1.1  mrg   output_asm_insn ("j\t%l0", &taken);
   2490  1.1  mrg 
   2491  1.1  mrg   /* Output NOT_TAKEN.  */
   2492  1.1  mrg   targetm.asm_out.internal_label (asm_out_file, "L",
   2493  1.1  mrg 				  CODE_LABEL_NUMBER (not_taken));
   2494  1.1  mrg   return "";
   2495  1.1  mrg }
   2496  1.1  mrg 
   2497  1.1  mrg 
   2498  1.1  mrg /* Output assembly code for a conditional branch instruction.  */
   2499  1.1  mrg const char *
   2500  1.1  mrg tilepro_output_cbranch (rtx_insn *insn, rtx *operands, bool reversed)
   2501  1.1  mrg {
   2502  1.1  mrg   enum rtx_code code = GET_CODE (operands[1]);
   2503  1.1  mrg   const char *opcode;
   2504  1.1  mrg   const char *rev_opcode;
   2505  1.1  mrg 
   2506  1.1  mrg   if (reversed)
   2507  1.1  mrg     code = reverse_condition (code);
   2508  1.1  mrg 
   2509  1.1  mrg   switch (code)
   2510  1.1  mrg     {
   2511  1.1  mrg     case NE:
   2512  1.1  mrg       opcode = "bnz";
   2513  1.1  mrg       rev_opcode = "bz";
   2514  1.1  mrg       break;
   2515  1.1  mrg     case EQ:
   2516  1.1  mrg       opcode = "bz";
   2517  1.1  mrg       rev_opcode = "bnz";
   2518  1.1  mrg       break;
   2519  1.1  mrg     case GE:
   2520  1.1  mrg       opcode = "bgez";
   2521  1.1  mrg       rev_opcode = "blz";
   2522  1.1  mrg       break;
   2523  1.1  mrg     case GT:
   2524  1.1  mrg       opcode = "bgz";
   2525  1.1  mrg       rev_opcode = "blez";
   2526  1.1  mrg       break;
   2527  1.1  mrg     case LE:
   2528  1.1  mrg       opcode = "blez";
   2529  1.1  mrg       rev_opcode = "bgz";
   2530  1.1  mrg       break;
   2531  1.1  mrg     case LT:
   2532  1.1  mrg       opcode = "blz";
   2533  1.1  mrg       rev_opcode = "bgez";
   2534  1.1  mrg       break;
   2535  1.1  mrg     default:
   2536  1.1  mrg       gcc_unreachable ();
   2537  1.1  mrg     }
   2538  1.1  mrg 
   2539  1.1  mrg   return
   2540  1.1  mrg     tilepro_output_cbranch_with_opcode (insn, operands, opcode, rev_opcode,
   2541  1.1  mrg 					2, false);
   2542  1.1  mrg }
   2543  1.1  mrg 
   2544  1.1  mrg 
   2545  1.1  mrg /* Implement the tablejump pattern.  */
   2546  1.1  mrg void
   2547  1.1  mrg tilepro_expand_tablejump (rtx op0, rtx op1)
   2548  1.1  mrg {
   2549  1.1  mrg   if (flag_pic)
   2550  1.1  mrg     {
   2551  1.1  mrg       rtx table = gen_rtx_LABEL_REF (Pmode, op1);
   2552  1.1  mrg       rtx temp = gen_reg_rtx (Pmode);
   2553  1.1  mrg       rtx text_label_symbol = tilepro_text_label_symbol ();
   2554  1.1  mrg       rtx text_label_rtx = tilepro_text_label_rtx ();
   2555  1.1  mrg 
   2556  1.1  mrg       emit_insn (gen_addli_pcrel (temp, text_label_rtx,
   2557  1.1  mrg 				  table, text_label_symbol));
   2558  1.1  mrg       emit_insn (gen_auli_pcrel (temp, temp, table, text_label_symbol));
   2559  1.1  mrg       emit_move_insn (temp,
   2560  1.1  mrg 		      gen_rtx_PLUS (Pmode,
   2561  1.1  mrg 				    convert_to_mode (Pmode, op0, false),
   2562  1.1  mrg 				    temp));
   2563  1.1  mrg       op0 = temp;
   2564  1.1  mrg     }
   2565  1.1  mrg 
   2566  1.1  mrg   emit_jump_insn (gen_tablejump_aux (op0, op1));
   2567  1.1  mrg }
   2568  1.1  mrg 
   2569  1.1  mrg 
   2570  1.1  mrg /* Expand a builtin vector binary op, by calling gen function GEN with
   2571  1.1  mrg    operands in the proper modes.  DEST is converted to DEST_MODE, and
   2572  1.1  mrg    src0 and src1 (if DO_SRC1 is true) is converted to SRC_MODE.  */
   2573  1.1  mrg void
   2574  1.1  mrg tilepro_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
   2575  1.1  mrg 				     machine_mode dest_mode,
   2576  1.1  mrg 				     rtx dest,
   2577  1.1  mrg 				     machine_mode src_mode,
   2578  1.1  mrg 				     rtx src0, rtx src1, bool do_src1)
   2579  1.1  mrg {
   2580  1.1  mrg   dest = gen_lowpart (dest_mode, dest);
   2581  1.1  mrg 
   2582  1.1  mrg   if (src0 == const0_rtx)
   2583  1.1  mrg     src0 = CONST0_RTX (src_mode);
   2584  1.1  mrg   else
   2585  1.1  mrg     src0 = gen_lowpart (src_mode, src0);
   2586  1.1  mrg 
   2587  1.1  mrg   if (do_src1)
   2588  1.1  mrg     {
   2589  1.1  mrg       if (src1 == const0_rtx)
   2590  1.1  mrg 	src1 = CONST0_RTX (src_mode);
   2591  1.1  mrg       else
   2592  1.1  mrg 	src1 = gen_lowpart (src_mode, src1);
   2593  1.1  mrg     }
   2594  1.1  mrg 
   2595  1.1  mrg   emit_insn ((*gen) (dest, src0, src1));
   2596  1.1  mrg }
   2597  1.1  mrg 
   2598  1.1  mrg 
   2600  1.1  mrg 
   2601  1.1  mrg /* Intrinsics  */
   2602  1.1  mrg 
   2603  1.1  mrg struct tile_builtin_info
   2604  1.1  mrg {
   2605  1.1  mrg   enum insn_code icode;
   2606  1.1  mrg   tree fndecl;
   2607  1.1  mrg };
   2608  1.1  mrg 
   2609  1.1  mrg static struct tile_builtin_info tilepro_builtin_info[TILEPRO_BUILTIN_max] = {
   2610  1.1  mrg   { CODE_FOR_addsi3,                    NULL }, /* add */
   2611  1.1  mrg   { CODE_FOR_insn_addb,                 NULL }, /* addb */
   2612  1.1  mrg   { CODE_FOR_insn_addbs_u,              NULL }, /* addbs_u */
   2613  1.1  mrg   { CODE_FOR_insn_addh,                 NULL }, /* addh */
   2614  1.1  mrg   { CODE_FOR_insn_addhs,                NULL }, /* addhs */
   2615  1.1  mrg   { CODE_FOR_insn_addib,                NULL }, /* addib */
   2616  1.1  mrg   { CODE_FOR_insn_addih,                NULL }, /* addih */
   2617  1.1  mrg   { CODE_FOR_insn_addlis,               NULL }, /* addlis */
   2618  1.1  mrg   { CODE_FOR_ssaddsi3,                  NULL }, /* adds */
   2619  1.1  mrg   { CODE_FOR_insn_adiffb_u,             NULL }, /* adiffb_u */
   2620  1.1  mrg   { CODE_FOR_insn_adiffh,               NULL }, /* adiffh */
   2621  1.1  mrg   { CODE_FOR_andsi3,                    NULL }, /* and */
   2622  1.1  mrg   { CODE_FOR_insn_auli,                 NULL }, /* auli */
   2623  1.1  mrg   { CODE_FOR_insn_avgb_u,               NULL }, /* avgb_u */
   2624  1.1  mrg   { CODE_FOR_insn_avgh,                 NULL }, /* avgh */
   2625  1.1  mrg   { CODE_FOR_insn_bitx,                 NULL }, /* bitx */
   2626  1.1  mrg   { CODE_FOR_bswapsi2,                  NULL }, /* bytex */
   2627  1.1  mrg   { CODE_FOR_clzsi2,                    NULL }, /* clz */
   2628  1.1  mrg   { CODE_FOR_insn_crc32_32,             NULL }, /* crc32_32 */
   2629  1.1  mrg   { CODE_FOR_insn_crc32_8,              NULL }, /* crc32_8 */
   2630  1.1  mrg   { CODE_FOR_ctzsi2,                    NULL }, /* ctz */
   2631  1.1  mrg   { CODE_FOR_insn_drain,                NULL }, /* drain */
   2632  1.1  mrg   { CODE_FOR_insn_dtlbpr,               NULL }, /* dtlbpr */
   2633  1.1  mrg   { CODE_FOR_insn_dword_align,          NULL }, /* dword_align */
   2634  1.1  mrg   { CODE_FOR_insn_finv,                 NULL }, /* finv */
   2635  1.1  mrg   { CODE_FOR_insn_flush,                NULL }, /* flush */
   2636  1.1  mrg   { CODE_FOR_insn_fnop,                 NULL }, /* fnop */
   2637  1.1  mrg   { CODE_FOR_insn_icoh,                 NULL }, /* icoh */
   2638  1.1  mrg   { CODE_FOR_insn_ill,                  NULL }, /* ill */
   2639  1.1  mrg   { CODE_FOR_insn_info,                 NULL }, /* info */
   2640  1.1  mrg   { CODE_FOR_insn_infol,                NULL }, /* infol */
   2641  1.1  mrg   { CODE_FOR_insn_inthb,                NULL }, /* inthb */
   2642  1.1  mrg   { CODE_FOR_insn_inthh,                NULL }, /* inthh */
   2643  1.1  mrg   { CODE_FOR_insn_intlb,                NULL }, /* intlb */
   2644  1.1  mrg   { CODE_FOR_insn_intlh,                NULL }, /* intlh */
   2645  1.1  mrg   { CODE_FOR_insn_inv,                  NULL }, /* inv */
   2646  1.1  mrg   { CODE_FOR_insn_lb,                   NULL }, /* lb */
   2647  1.1  mrg   { CODE_FOR_insn_lb_u,                 NULL }, /* lb_u */
   2648  1.1  mrg   { CODE_FOR_insn_lh,                   NULL }, /* lh */
   2649  1.1  mrg   { CODE_FOR_insn_lh_u,                 NULL }, /* lh_u */
   2650  1.1  mrg   { CODE_FOR_insn_lnk,                  NULL }, /* lnk */
   2651  1.1  mrg   { CODE_FOR_insn_lw,                   NULL }, /* lw */
   2652  1.1  mrg   { CODE_FOR_insn_lw_na,                NULL }, /* lw_na */
   2653  1.1  mrg   { CODE_FOR_insn_lb_L2,                NULL }, /* lb_L2 */
   2654  1.1  mrg   { CODE_FOR_insn_lb_u_L2,              NULL }, /* lb_u_L2 */
   2655  1.1  mrg   { CODE_FOR_insn_lh_L2,                NULL }, /* lh_L2 */
   2656  1.1  mrg   { CODE_FOR_insn_lh_u_L2,              NULL }, /* lh_u_L2 */
   2657  1.1  mrg   { CODE_FOR_insn_lw_L2,                NULL }, /* lw_L2 */
   2658  1.1  mrg   { CODE_FOR_insn_lw_na_L2,             NULL }, /* lw_na_L2 */
   2659  1.1  mrg   { CODE_FOR_insn_lb_miss,              NULL }, /* lb_miss */
   2660  1.1  mrg   { CODE_FOR_insn_lb_u_miss,            NULL }, /* lb_u_miss */
   2661  1.1  mrg   { CODE_FOR_insn_lh_miss,              NULL }, /* lh_miss */
   2662  1.1  mrg   { CODE_FOR_insn_lh_u_miss,            NULL }, /* lh_u_miss */
   2663  1.1  mrg   { CODE_FOR_insn_lw_miss,              NULL }, /* lw_miss */
   2664  1.1  mrg   { CODE_FOR_insn_lw_na_miss,           NULL }, /* lw_na_miss */
   2665  1.1  mrg   { CODE_FOR_insn_maxb_u,               NULL }, /* maxb_u */
   2666  1.1  mrg   { CODE_FOR_insn_maxh,                 NULL }, /* maxh */
   2667  1.1  mrg   { CODE_FOR_insn_maxib_u,              NULL }, /* maxib_u */
   2668  1.1  mrg   { CODE_FOR_insn_maxih,                NULL }, /* maxih */
   2669  1.1  mrg   { CODE_FOR_memory_barrier,            NULL }, /* mf */
   2670  1.1  mrg   { CODE_FOR_insn_mfspr,                NULL }, /* mfspr */
   2671  1.1  mrg   { CODE_FOR_insn_minb_u,               NULL }, /* minb_u */
   2672  1.1  mrg   { CODE_FOR_insn_minh,                 NULL }, /* minh */
   2673  1.1  mrg   { CODE_FOR_insn_minib_u,              NULL }, /* minib_u */
   2674  1.1  mrg   { CODE_FOR_insn_minih,                NULL }, /* minih */
   2675  1.1  mrg   { CODE_FOR_insn_mm,                   NULL }, /* mm */
   2676  1.1  mrg   { CODE_FOR_insn_mnz,                  NULL }, /* mnz */
   2677  1.1  mrg   { CODE_FOR_insn_mnzb,                 NULL }, /* mnzb */
   2678  1.1  mrg   { CODE_FOR_insn_mnzh,                 NULL }, /* mnzh */
   2679  1.1  mrg   { CODE_FOR_movsi,                     NULL }, /* move */
   2680  1.1  mrg   { CODE_FOR_insn_movelis,              NULL }, /* movelis */
   2681  1.1  mrg   { CODE_FOR_insn_mtspr,                NULL }, /* mtspr */
   2682  1.1  mrg   { CODE_FOR_insn_mulhh_ss,             NULL }, /* mulhh_ss */
   2683  1.1  mrg   { CODE_FOR_insn_mulhh_su,             NULL }, /* mulhh_su */
   2684  1.1  mrg   { CODE_FOR_insn_mulhh_uu,             NULL }, /* mulhh_uu */
   2685  1.1  mrg   { CODE_FOR_insn_mulhha_ss,            NULL }, /* mulhha_ss */
   2686  1.1  mrg   { CODE_FOR_insn_mulhha_su,            NULL }, /* mulhha_su */
   2687  1.1  mrg   { CODE_FOR_insn_mulhha_uu,            NULL }, /* mulhha_uu */
   2688  1.1  mrg   { CODE_FOR_insn_mulhhsa_uu,           NULL }, /* mulhhsa_uu */
   2689  1.1  mrg   { CODE_FOR_insn_mulhl_ss,             NULL }, /* mulhl_ss */
   2690  1.1  mrg   { CODE_FOR_insn_mulhl_su,             NULL }, /* mulhl_su */
   2691  1.1  mrg   { CODE_FOR_insn_mulhl_us,             NULL }, /* mulhl_us */
   2692  1.1  mrg   { CODE_FOR_insn_mulhl_uu,             NULL }, /* mulhl_uu */
   2693  1.1  mrg   { CODE_FOR_insn_mulhla_ss,            NULL }, /* mulhla_ss */
   2694  1.1  mrg   { CODE_FOR_insn_mulhla_su,            NULL }, /* mulhla_su */
   2695  1.1  mrg   { CODE_FOR_insn_mulhla_us,            NULL }, /* mulhla_us */
   2696  1.1  mrg   { CODE_FOR_insn_mulhla_uu,            NULL }, /* mulhla_uu */
   2697  1.1  mrg   { CODE_FOR_insn_mulhlsa_uu,           NULL }, /* mulhlsa_uu */
   2698  1.1  mrg   { CODE_FOR_insn_mulll_ss,             NULL }, /* mulll_ss */
   2699  1.1  mrg   { CODE_FOR_insn_mulll_su,             NULL }, /* mulll_su */
   2700  1.1  mrg   { CODE_FOR_insn_mulll_uu,             NULL }, /* mulll_uu */
   2701  1.1  mrg   { CODE_FOR_insn_mullla_ss,            NULL }, /* mullla_ss */
   2702  1.1  mrg   { CODE_FOR_insn_mullla_su,            NULL }, /* mullla_su */
   2703  1.1  mrg   { CODE_FOR_insn_mullla_uu,            NULL }, /* mullla_uu */
   2704  1.1  mrg   { CODE_FOR_insn_mulllsa_uu,           NULL }, /* mulllsa_uu */
   2705  1.1  mrg   { CODE_FOR_insn_mvnz,                 NULL }, /* mvnz */
   2706  1.1  mrg   { CODE_FOR_insn_mvz,                  NULL }, /* mvz */
   2707  1.1  mrg   { CODE_FOR_insn_mz,                   NULL }, /* mz */
   2708  1.1  mrg   { CODE_FOR_insn_mzb,                  NULL }, /* mzb */
   2709  1.1  mrg   { CODE_FOR_insn_mzh,                  NULL }, /* mzh */
   2710  1.1  mrg   { CODE_FOR_insn_nap,                  NULL }, /* nap */
   2711  1.1  mrg   { CODE_FOR_nop,                       NULL }, /* nop */
   2712  1.1  mrg   { CODE_FOR_insn_nor,                  NULL }, /* nor */
   2713  1.1  mrg   { CODE_FOR_iorsi3,                    NULL }, /* or */
   2714  1.1  mrg   { CODE_FOR_insn_packbs_u,             NULL }, /* packbs_u */
   2715  1.1  mrg   { CODE_FOR_insn_packhb,               NULL }, /* packhb */
   2716  1.1  mrg   { CODE_FOR_insn_packhs,               NULL }, /* packhs */
   2717  1.1  mrg   { CODE_FOR_insn_packlb,               NULL }, /* packlb */
   2718  1.1  mrg   { CODE_FOR_popcountsi2,               NULL }, /* pcnt */
   2719  1.1  mrg   { CODE_FOR_insn_prefetch,             NULL }, /* prefetch */
   2720  1.1  mrg   { CODE_FOR_insn_prefetch_L1,          NULL }, /* prefetch_L1 */
   2721  1.1  mrg   { CODE_FOR_rotlsi3,                   NULL }, /* rl */
   2722  1.1  mrg   { CODE_FOR_insn_s1a,                  NULL }, /* s1a */
   2723  1.1  mrg   { CODE_FOR_insn_s2a,                  NULL }, /* s2a */
   2724  1.1  mrg   { CODE_FOR_insn_s3a,                  NULL }, /* s3a */
   2725  1.1  mrg   { CODE_FOR_insn_sadab_u,              NULL }, /* sadab_u */
   2726  1.1  mrg   { CODE_FOR_insn_sadah,                NULL }, /* sadah */
   2727  1.1  mrg   { CODE_FOR_insn_sadah_u,              NULL }, /* sadah_u */
   2728  1.1  mrg   { CODE_FOR_insn_sadb_u,               NULL }, /* sadb_u */
   2729  1.1  mrg   { CODE_FOR_insn_sadh,                 NULL }, /* sadh */
   2730  1.1  mrg   { CODE_FOR_insn_sadh_u,               NULL }, /* sadh_u */
   2731  1.1  mrg   { CODE_FOR_insn_sb,                   NULL }, /* sb */
   2732  1.1  mrg   { CODE_FOR_insn_seq,                  NULL }, /* seq */
   2733  1.1  mrg   { CODE_FOR_insn_seqb,                 NULL }, /* seqb */
   2734  1.1  mrg   { CODE_FOR_insn_seqh,                 NULL }, /* seqh */
   2735  1.1  mrg   { CODE_FOR_insn_seqib,                NULL }, /* seqib */
   2736  1.1  mrg   { CODE_FOR_insn_seqih,                NULL }, /* seqih */
   2737  1.1  mrg   { CODE_FOR_insn_sh,                   NULL }, /* sh */
   2738  1.1  mrg   { CODE_FOR_ashlsi3,                   NULL }, /* shl */
   2739  1.1  mrg   { CODE_FOR_insn_shlb,                 NULL }, /* shlb */
   2740  1.1  mrg   { CODE_FOR_insn_shlh,                 NULL }, /* shlh */
   2741  1.1  mrg   { CODE_FOR_insn_shlb,                 NULL }, /* shlib */
   2742  1.1  mrg   { CODE_FOR_insn_shlh,                 NULL }, /* shlih */
   2743  1.1  mrg   { CODE_FOR_lshrsi3,                   NULL }, /* shr */
   2744  1.1  mrg   { CODE_FOR_insn_shrb,                 NULL }, /* shrb */
   2745  1.1  mrg   { CODE_FOR_insn_shrh,                 NULL }, /* shrh */
   2746  1.1  mrg   { CODE_FOR_insn_shrb,                 NULL }, /* shrib */
   2747  1.1  mrg   { CODE_FOR_insn_shrh,                 NULL }, /* shrih */
   2748  1.1  mrg   { CODE_FOR_insn_slt,                  NULL }, /* slt */
   2749  1.1  mrg   { CODE_FOR_insn_slt_u,                NULL }, /* slt_u */
   2750  1.1  mrg   { CODE_FOR_insn_sltb,                 NULL }, /* sltb */
   2751  1.1  mrg   { CODE_FOR_insn_sltb_u,               NULL }, /* sltb_u */
   2752  1.1  mrg   { CODE_FOR_insn_slte,                 NULL }, /* slte */
   2753  1.1  mrg   { CODE_FOR_insn_slte_u,               NULL }, /* slte_u */
   2754  1.1  mrg   { CODE_FOR_insn_slteb,                NULL }, /* slteb */
   2755  1.1  mrg   { CODE_FOR_insn_slteb_u,              NULL }, /* slteb_u */
   2756  1.1  mrg   { CODE_FOR_insn_slteh,                NULL }, /* slteh */
   2757  1.1  mrg   { CODE_FOR_insn_slteh_u,              NULL }, /* slteh_u */
   2758  1.1  mrg   { CODE_FOR_insn_slth,                 NULL }, /* slth */
   2759  1.1  mrg   { CODE_FOR_insn_slth_u,               NULL }, /* slth_u */
   2760  1.1  mrg   { CODE_FOR_insn_sltib,                NULL }, /* sltib */
   2761  1.1  mrg   { CODE_FOR_insn_sltib_u,              NULL }, /* sltib_u */
   2762  1.1  mrg   { CODE_FOR_insn_sltih,                NULL }, /* sltih */
   2763  1.1  mrg   { CODE_FOR_insn_sltih_u,              NULL }, /* sltih_u */
   2764  1.1  mrg   { CODE_FOR_insn_sne,                  NULL }, /* sne */
   2765  1.1  mrg   { CODE_FOR_insn_sneb,                 NULL }, /* sneb */
   2766  1.1  mrg   { CODE_FOR_insn_sneh,                 NULL }, /* sneh */
   2767  1.1  mrg   { CODE_FOR_ashrsi3,                   NULL }, /* sra */
   2768  1.1  mrg   { CODE_FOR_insn_srab,                 NULL }, /* srab */
   2769  1.1  mrg   { CODE_FOR_insn_srah,                 NULL }, /* srah */
   2770  1.1  mrg   { CODE_FOR_insn_srab,                 NULL }, /* sraib */
   2771  1.1  mrg   { CODE_FOR_insn_srah,                 NULL }, /* sraih */
   2772  1.1  mrg   { CODE_FOR_subsi3,                    NULL }, /* sub */
   2773  1.1  mrg   { CODE_FOR_insn_subb,                 NULL }, /* subb */
   2774  1.1  mrg   { CODE_FOR_insn_subbs_u,              NULL }, /* subbs_u */
   2775  1.1  mrg   { CODE_FOR_insn_subh,                 NULL }, /* subh */
   2776  1.1  mrg   { CODE_FOR_insn_subhs,                NULL }, /* subhs */
   2777  1.1  mrg   { CODE_FOR_sssubsi3,                  NULL }, /* subs */
   2778  1.1  mrg   { CODE_FOR_insn_sw,                   NULL }, /* sw */
   2779  1.1  mrg   { CODE_FOR_insn_tblidxb0,             NULL }, /* tblidxb0 */
   2780  1.1  mrg   { CODE_FOR_insn_tblidxb1,             NULL }, /* tblidxb1 */
   2781  1.1  mrg   { CODE_FOR_insn_tblidxb2,             NULL }, /* tblidxb2 */
   2782  1.1  mrg   { CODE_FOR_insn_tblidxb3,             NULL }, /* tblidxb3 */
   2783  1.1  mrg   { CODE_FOR_insn_tns,                  NULL }, /* tns */
   2784  1.1  mrg   { CODE_FOR_insn_wh64,                 NULL }, /* wh64 */
   2785  1.1  mrg   { CODE_FOR_xorsi3,                    NULL }, /* xor */
   2786  1.1  mrg   { CODE_FOR_tilepro_network_barrier,   NULL }, /* network_barrier */
   2787  1.1  mrg   { CODE_FOR_tilepro_idn0_receive,      NULL }, /* idn0_receive */
   2788  1.1  mrg   { CODE_FOR_tilepro_idn1_receive,      NULL }, /* idn1_receive */
   2789  1.1  mrg   { CODE_FOR_tilepro_idn_send,          NULL }, /* idn_send */
   2790  1.1  mrg   { CODE_FOR_tilepro_sn_receive,        NULL }, /* sn_receive */
   2791  1.1  mrg   { CODE_FOR_tilepro_sn_send,           NULL }, /* sn_send */
   2792  1.1  mrg   { CODE_FOR_tilepro_udn0_receive,      NULL }, /* udn0_receive */
   2793  1.1  mrg   { CODE_FOR_tilepro_udn1_receive,      NULL }, /* udn1_receive */
   2794  1.1  mrg   { CODE_FOR_tilepro_udn2_receive,      NULL }, /* udn2_receive */
   2795  1.1  mrg   { CODE_FOR_tilepro_udn3_receive,      NULL }, /* udn3_receive */
   2796  1.1  mrg   { CODE_FOR_tilepro_udn_send,          NULL }, /* udn_send */
   2797  1.1  mrg };
   2798  1.1  mrg 
   2799  1.1  mrg 
   2800  1.1  mrg struct tilepro_builtin_def
   2801  1.1  mrg {
   2802  1.1  mrg   const char *name;
   2803  1.1  mrg   enum tilepro_builtin code;
   2804  1.1  mrg   bool is_const;
   2805  1.1  mrg   /* The first character is the return type.  Subsequent characters
   2806  1.1  mrg      are the argument types. See char_to_type.  */
   2807  1.1  mrg   const char *type;
   2808  1.1  mrg };
   2809  1.1  mrg 
   2810  1.1  mrg 
   2811  1.1  mrg static const struct tilepro_builtin_def tilepro_builtins[] = {
   2812  1.1  mrg   { "__insn_add",             TILEPRO_INSN_ADD,         true,  "lll"   },
   2813  1.1  mrg   { "__insn_addb",            TILEPRO_INSN_ADDB,        true,  "lll"   },
   2814  1.1  mrg   { "__insn_addbs_u",         TILEPRO_INSN_ADDBS_U,     false, "lll"   },
   2815  1.1  mrg   { "__insn_addh",            TILEPRO_INSN_ADDH,        true,  "lll"   },
   2816  1.1  mrg   { "__insn_addhs",           TILEPRO_INSN_ADDHS,       false, "lll"   },
   2817  1.1  mrg   { "__insn_addi",            TILEPRO_INSN_ADD,         true,  "lll"   },
   2818  1.1  mrg   { "__insn_addib",           TILEPRO_INSN_ADDIB,       true,  "lll"   },
   2819  1.1  mrg   { "__insn_addih",           TILEPRO_INSN_ADDIH,       true,  "lll"   },
   2820  1.1  mrg   { "__insn_addli",           TILEPRO_INSN_ADD,         true,  "lll"   },
   2821  1.1  mrg   { "__insn_addlis",          TILEPRO_INSN_ADDLIS,      false, "lll"   },
   2822  1.1  mrg   { "__insn_adds",            TILEPRO_INSN_ADDS,        false, "lll"   },
   2823  1.1  mrg   { "__insn_adiffb_u",        TILEPRO_INSN_ADIFFB_U,    true,  "lll"   },
   2824  1.1  mrg   { "__insn_adiffh",          TILEPRO_INSN_ADIFFH,      true,  "lll"   },
   2825  1.1  mrg   { "__insn_and",             TILEPRO_INSN_AND,         true,  "lll"   },
   2826  1.1  mrg   { "__insn_andi",            TILEPRO_INSN_AND,         true,  "lll"   },
   2827  1.1  mrg   { "__insn_auli",            TILEPRO_INSN_AULI,        true,  "lll"   },
   2828  1.1  mrg   { "__insn_avgb_u",          TILEPRO_INSN_AVGB_U,      true,  "lll"   },
   2829  1.1  mrg   { "__insn_avgh",            TILEPRO_INSN_AVGH,        true,  "lll"   },
   2830  1.1  mrg   { "__insn_bitx",            TILEPRO_INSN_BITX,        true,  "ll"    },
   2831  1.1  mrg   { "__insn_bytex",           TILEPRO_INSN_BYTEX,       true,  "ll"    },
   2832  1.1  mrg   { "__insn_clz",             TILEPRO_INSN_CLZ,         true,  "ll"    },
   2833  1.1  mrg   { "__insn_crc32_32",        TILEPRO_INSN_CRC32_32,    true,  "lll"   },
   2834  1.1  mrg   { "__insn_crc32_8",         TILEPRO_INSN_CRC32_8,     true,  "lll"   },
   2835  1.1  mrg   { "__insn_ctz",             TILEPRO_INSN_CTZ,         true,  "ll"    },
   2836  1.1  mrg   { "__insn_drain",           TILEPRO_INSN_DRAIN,       false, "v"     },
   2837  1.1  mrg   { "__insn_dtlbpr",          TILEPRO_INSN_DTLBPR,      false, "vl"    },
   2838  1.1  mrg   { "__insn_dword_align",     TILEPRO_INSN_DWORD_ALIGN, true,  "lllk"  },
   2839  1.1  mrg   { "__insn_finv",            TILEPRO_INSN_FINV,        false, "vk"    },
   2840  1.1  mrg   { "__insn_flush",           TILEPRO_INSN_FLUSH,       false, "vk"    },
   2841  1.1  mrg   { "__insn_fnop",            TILEPRO_INSN_FNOP,        false, "v"     },
   2842  1.1  mrg   { "__insn_icoh",            TILEPRO_INSN_ICOH,        false, "vk"    },
   2843  1.1  mrg   { "__insn_ill",             TILEPRO_INSN_ILL,         false, "v"     },
   2844  1.1  mrg   { "__insn_info",            TILEPRO_INSN_INFO,        false, "vl"    },
   2845  1.1  mrg   { "__insn_infol",           TILEPRO_INSN_INFOL,       false, "vl"    },
   2846  1.1  mrg   { "__insn_inthb",           TILEPRO_INSN_INTHB,       true,  "lll"   },
   2847  1.1  mrg   { "__insn_inthh",           TILEPRO_INSN_INTHH,       true,  "lll"   },
   2848  1.1  mrg   { "__insn_intlb",           TILEPRO_INSN_INTLB,       true,  "lll"   },
   2849  1.1  mrg   { "__insn_intlh",           TILEPRO_INSN_INTLH,       true,  "lll"   },
   2850  1.1  mrg   { "__insn_inv",             TILEPRO_INSN_INV,         false, "vp"    },
   2851  1.1  mrg   { "__insn_lb",              TILEPRO_INSN_LB,          false, "lk"    },
   2852  1.1  mrg   { "__insn_lb_u",            TILEPRO_INSN_LB_U,        false, "lk"    },
   2853  1.1  mrg   { "__insn_lh",              TILEPRO_INSN_LH,          false, "lk"    },
   2854  1.1  mrg   { "__insn_lh_u",            TILEPRO_INSN_LH_U,        false, "lk"    },
   2855  1.1  mrg   { "__insn_lnk",             TILEPRO_INSN_LNK,         true,  "l"     },
   2856  1.1  mrg   { "__insn_lw",              TILEPRO_INSN_LW,          false, "lk"    },
   2857  1.1  mrg   { "__insn_lw_na",           TILEPRO_INSN_LW_NA,       false, "lk"    },
   2858  1.1  mrg   { "__insn_lb_L2",           TILEPRO_INSN_LB_L2,       false, "lk"    },
   2859  1.1  mrg   { "__insn_lb_u_L2",         TILEPRO_INSN_LB_U_L2,     false, "lk"    },
   2860  1.1  mrg   { "__insn_lh_L2",           TILEPRO_INSN_LH_L2,       false, "lk"    },
   2861  1.1  mrg   { "__insn_lh_u_L2",         TILEPRO_INSN_LH_U_L2,     false, "lk"    },
   2862  1.1  mrg   { "__insn_lw_L2",           TILEPRO_INSN_LW_L2,       false, "lk"    },
   2863  1.1  mrg   { "__insn_lw_na_L2",        TILEPRO_INSN_LW_NA_L2,    false, "lk"    },
   2864  1.1  mrg   { "__insn_lb_miss",         TILEPRO_INSN_LB_MISS,     false, "lk"    },
   2865  1.1  mrg   { "__insn_lb_u_miss",       TILEPRO_INSN_LB_U_MISS,   false, "lk"    },
   2866  1.1  mrg   { "__insn_lh_miss",         TILEPRO_INSN_LH_MISS,     false, "lk"    },
   2867  1.1  mrg   { "__insn_lh_u_miss",       TILEPRO_INSN_LH_U_MISS,   false, "lk"    },
   2868  1.1  mrg   { "__insn_lw_miss",         TILEPRO_INSN_LW_MISS,     false, "lk"    },
   2869  1.1  mrg   { "__insn_lw_na_miss",      TILEPRO_INSN_LW_NA_MISS,  false, "lk"    },
   2870  1.1  mrg   { "__insn_maxb_u",          TILEPRO_INSN_MAXB_U,      true,  "lll"   },
   2871  1.1  mrg   { "__insn_maxh",            TILEPRO_INSN_MAXH,        true,  "lll"   },
   2872  1.1  mrg   { "__insn_maxib_u",         TILEPRO_INSN_MAXIB_U,     true,  "lll"   },
   2873  1.1  mrg   { "__insn_maxih",           TILEPRO_INSN_MAXIH,       true,  "lll"   },
   2874  1.1  mrg   { "__insn_mf",              TILEPRO_INSN_MF,          false, "v"     },
   2875  1.1  mrg   { "__insn_mfspr",           TILEPRO_INSN_MFSPR,       false, "ll"    },
   2876  1.1  mrg   { "__insn_minb_u",          TILEPRO_INSN_MINB_U,      true,  "lll"   },
   2877  1.1  mrg   { "__insn_minh",            TILEPRO_INSN_MINH,        true,  "lll"   },
   2878  1.1  mrg   { "__insn_minib_u",         TILEPRO_INSN_MINIB_U,     true,  "lll"   },
   2879  1.1  mrg   { "__insn_minih",           TILEPRO_INSN_MINIH,       true,  "lll"   },
   2880  1.1  mrg   { "__insn_mm",              TILEPRO_INSN_MM,          true,  "lllll" },
   2881  1.1  mrg   { "__insn_mnz",             TILEPRO_INSN_MNZ,         true,  "lll"   },
   2882  1.1  mrg   { "__insn_mnzb",            TILEPRO_INSN_MNZB,        true,  "lll"   },
   2883  1.1  mrg   { "__insn_mnzh",            TILEPRO_INSN_MNZH,        true,  "lll"   },
   2884  1.1  mrg   { "__insn_move",            TILEPRO_INSN_MOVE,        true,  "ll"    },
   2885  1.1  mrg   { "__insn_movei",           TILEPRO_INSN_MOVE,        true,  "ll"    },
   2886  1.1  mrg   { "__insn_moveli",          TILEPRO_INSN_MOVE,        true,  "ll"    },
   2887  1.1  mrg   { "__insn_movelis",         TILEPRO_INSN_MOVELIS,     false, "ll"    },
   2888  1.1  mrg   { "__insn_mtspr",           TILEPRO_INSN_MTSPR,       false, "vll"   },
   2889  1.1  mrg   { "__insn_mulhh_ss",        TILEPRO_INSN_MULHH_SS,    true,  "lll"   },
   2890  1.1  mrg   { "__insn_mulhh_su",        TILEPRO_INSN_MULHH_SU,    true,  "lll"   },
   2891  1.1  mrg   { "__insn_mulhh_uu",        TILEPRO_INSN_MULHH_UU,    true,  "lll"   },
   2892  1.1  mrg   { "__insn_mulhha_ss",       TILEPRO_INSN_MULHHA_SS,   true,  "llll"  },
   2893  1.1  mrg   { "__insn_mulhha_su",       TILEPRO_INSN_MULHHA_SU,   true,  "llll"  },
   2894  1.1  mrg   { "__insn_mulhha_uu",       TILEPRO_INSN_MULHHA_UU,   true,  "llll"  },
   2895  1.1  mrg   { "__insn_mulhhsa_uu",      TILEPRO_INSN_MULHHSA_UU,  true,  "llll"  },
   2896  1.1  mrg   { "__insn_mulhl_ss",        TILEPRO_INSN_MULHL_SS,    true,  "lll"   },
   2897  1.1  mrg   { "__insn_mulhl_su",        TILEPRO_INSN_MULHL_SU,    true,  "lll"   },
   2898  1.1  mrg   { "__insn_mulhl_us",        TILEPRO_INSN_MULHL_US,    true,  "lll"   },
   2899  1.1  mrg   { "__insn_mulhl_uu",        TILEPRO_INSN_MULHL_UU,    true,  "lll"   },
   2900  1.1  mrg   { "__insn_mulhla_ss",       TILEPRO_INSN_MULHLA_SS,   true,  "llll"  },
   2901  1.1  mrg   { "__insn_mulhla_su",       TILEPRO_INSN_MULHLA_SU,   true,  "llll"  },
   2902  1.1  mrg   { "__insn_mulhla_us",       TILEPRO_INSN_MULHLA_US,   true,  "llll"  },
   2903  1.1  mrg   { "__insn_mulhla_uu",       TILEPRO_INSN_MULHLA_UU,   true,  "llll"  },
   2904  1.1  mrg   { "__insn_mulhlsa_uu",      TILEPRO_INSN_MULHLSA_UU,  true,  "llll"  },
   2905  1.1  mrg   { "__insn_mulll_ss",        TILEPRO_INSN_MULLL_SS,    true,  "lll"   },
   2906  1.1  mrg   { "__insn_mulll_su",        TILEPRO_INSN_MULLL_SU,    true,  "lll"   },
   2907  1.1  mrg   { "__insn_mulll_uu",        TILEPRO_INSN_MULLL_UU,    true,  "lll"   },
   2908  1.1  mrg   { "__insn_mullla_ss",       TILEPRO_INSN_MULLLA_SS,   true,  "llll"  },
   2909  1.1  mrg   { "__insn_mullla_su",       TILEPRO_INSN_MULLLA_SU,   true,  "llll"  },
   2910  1.1  mrg   { "__insn_mullla_uu",       TILEPRO_INSN_MULLLA_UU,   true,  "llll"  },
   2911  1.1  mrg   { "__insn_mulllsa_uu",      TILEPRO_INSN_MULLLSA_UU,  true,  "llll"  },
   2912  1.1  mrg   { "__insn_mvnz",            TILEPRO_INSN_MVNZ,        true,  "llll"  },
   2913  1.1  mrg   { "__insn_mvz",             TILEPRO_INSN_MVZ,         true,  "llll"  },
   2914  1.1  mrg   { "__insn_mz",              TILEPRO_INSN_MZ,          true,  "lll"   },
   2915  1.1  mrg   { "__insn_mzb",             TILEPRO_INSN_MZB,         true,  "lll"   },
   2916  1.1  mrg   { "__insn_mzh",             TILEPRO_INSN_MZH,         true,  "lll"   },
   2917  1.1  mrg   { "__insn_nap",             TILEPRO_INSN_NAP,         false, "v"     },
   2918  1.1  mrg   { "__insn_nop",             TILEPRO_INSN_NOP,         true,  "v"     },
   2919  1.1  mrg   { "__insn_nor",             TILEPRO_INSN_NOR,         true,  "lll"   },
   2920  1.1  mrg   { "__insn_or",              TILEPRO_INSN_OR,          true,  "lll"   },
   2921  1.1  mrg   { "__insn_ori",             TILEPRO_INSN_OR,          true,  "lll"   },
   2922  1.1  mrg   { "__insn_packbs_u",        TILEPRO_INSN_PACKBS_U,    false, "lll"   },
   2923  1.1  mrg   { "__insn_packhb",          TILEPRO_INSN_PACKHB,      true,  "lll"   },
   2924  1.1  mrg   { "__insn_packhs",          TILEPRO_INSN_PACKHS,      false, "lll"   },
   2925  1.1  mrg   { "__insn_packlb",          TILEPRO_INSN_PACKLB,      true,  "lll"   },
   2926  1.1  mrg   { "__insn_pcnt",            TILEPRO_INSN_PCNT,        true,  "ll"    },
   2927  1.1  mrg   { "__insn_prefetch",        TILEPRO_INSN_PREFETCH,    false, "vk"    },
   2928  1.1  mrg   { "__insn_prefetch_L1",     TILEPRO_INSN_PREFETCH_L1, false, "vk"    },
   2929  1.1  mrg   { "__insn_rl",              TILEPRO_INSN_RL,          true,  "lll"   },
   2930  1.1  mrg   { "__insn_rli",             TILEPRO_INSN_RL,          true,  "lll"   },
   2931  1.1  mrg   { "__insn_s1a",             TILEPRO_INSN_S1A,         true,  "lll"   },
   2932  1.1  mrg   { "__insn_s2a",             TILEPRO_INSN_S2A,         true,  "lll"   },
   2933  1.1  mrg   { "__insn_s3a",             TILEPRO_INSN_S3A,         true,  "lll"   },
   2934  1.1  mrg   { "__insn_sadab_u",         TILEPRO_INSN_SADAB_U,     true,  "llll"  },
   2935  1.1  mrg   { "__insn_sadah",           TILEPRO_INSN_SADAH,       true,  "llll"  },
   2936  1.1  mrg   { "__insn_sadah_u",         TILEPRO_INSN_SADAH_U,     true,  "llll"  },
   2937  1.1  mrg   { "__insn_sadb_u",          TILEPRO_INSN_SADB_U,      true,  "lll"   },
   2938  1.1  mrg   { "__insn_sadh",            TILEPRO_INSN_SADH,        true,  "lll"   },
   2939  1.1  mrg   { "__insn_sadh_u",          TILEPRO_INSN_SADH_U,      true,  "lll"   },
   2940  1.1  mrg   { "__insn_sb",              TILEPRO_INSN_SB,          false, "vpl"   },
   2941  1.1  mrg   { "__insn_seq",             TILEPRO_INSN_SEQ,         true,  "lll"   },
   2942  1.1  mrg   { "__insn_seqb",            TILEPRO_INSN_SEQB,        true,  "lll"   },
   2943  1.1  mrg   { "__insn_seqh",            TILEPRO_INSN_SEQH,        true,  "lll"   },
   2944  1.1  mrg   { "__insn_seqi",            TILEPRO_INSN_SEQ,         true,  "lll"   },
   2945  1.1  mrg   { "__insn_seqib",           TILEPRO_INSN_SEQIB,       true,  "lll"   },
   2946  1.1  mrg   { "__insn_seqih",           TILEPRO_INSN_SEQIH,       true,  "lll"   },
   2947  1.1  mrg   { "__insn_sh",              TILEPRO_INSN_SH,          false, "vpl"   },
   2948  1.1  mrg   { "__insn_shl",             TILEPRO_INSN_SHL,         true,  "lll"   },
   2949  1.1  mrg   { "__insn_shlb",            TILEPRO_INSN_SHLB,        true,  "lll"   },
   2950  1.1  mrg   { "__insn_shlh",            TILEPRO_INSN_SHLH,        true,  "lll"   },
   2951  1.1  mrg   { "__insn_shli",            TILEPRO_INSN_SHL,         true,  "lll"   },
   2952  1.1  mrg   { "__insn_shlib",           TILEPRO_INSN_SHLIB,       true,  "lll"   },
   2953  1.1  mrg   { "__insn_shlih",           TILEPRO_INSN_SHLIH,       true,  "lll"   },
   2954  1.1  mrg   { "__insn_shr",             TILEPRO_INSN_SHR,         true,  "lll"   },
   2955  1.1  mrg   { "__insn_shrb",            TILEPRO_INSN_SHRB,        true,  "lll"   },
   2956  1.1  mrg   { "__insn_shrh",            TILEPRO_INSN_SHRH,        true,  "lll"   },
   2957  1.1  mrg   { "__insn_shri",            TILEPRO_INSN_SHR,         true,  "lll"   },
   2958  1.1  mrg   { "__insn_shrib",           TILEPRO_INSN_SHRIB,       true,  "lll"   },
   2959  1.1  mrg   { "__insn_shrih",           TILEPRO_INSN_SHRIH,       true,  "lll"   },
   2960  1.1  mrg   { "__insn_slt",             TILEPRO_INSN_SLT,         true,  "lll"   },
   2961  1.1  mrg   { "__insn_slt_u",           TILEPRO_INSN_SLT_U,       true,  "lll"   },
   2962  1.1  mrg   { "__insn_sltb",            TILEPRO_INSN_SLTB,        true,  "lll"   },
   2963  1.1  mrg   { "__insn_sltb_u",          TILEPRO_INSN_SLTB_U,      true,  "lll"   },
   2964  1.1  mrg   { "__insn_slte",            TILEPRO_INSN_SLTE,        true,  "lll"   },
   2965  1.1  mrg   { "__insn_slte_u",          TILEPRO_INSN_SLTE_U,      true,  "lll"   },
   2966  1.1  mrg   { "__insn_slteb",           TILEPRO_INSN_SLTEB,       true,  "lll"   },
   2967  1.1  mrg   { "__insn_slteb_u",         TILEPRO_INSN_SLTEB_U,     true,  "lll"   },
   2968  1.1  mrg   { "__insn_slteh",           TILEPRO_INSN_SLTEH,       true,  "lll"   },
   2969  1.1  mrg   { "__insn_slteh_u",         TILEPRO_INSN_SLTEH_U,     true,  "lll"   },
   2970  1.1  mrg   { "__insn_slth",            TILEPRO_INSN_SLTH,        true,  "lll"   },
   2971  1.1  mrg   { "__insn_slth_u",          TILEPRO_INSN_SLTH_U,      true,  "lll"   },
   2972  1.1  mrg   { "__insn_slti",            TILEPRO_INSN_SLT,         true,  "lll"   },
   2973  1.1  mrg   { "__insn_slti_u",          TILEPRO_INSN_SLT_U,       true,  "lll"   },
   2974  1.1  mrg   { "__insn_sltib",           TILEPRO_INSN_SLTIB,       true,  "lll"   },
   2975  1.1  mrg   { "__insn_sltib_u",         TILEPRO_INSN_SLTIB_U,     true,  "lll"   },
   2976  1.1  mrg   { "__insn_sltih",           TILEPRO_INSN_SLTIH,       true,  "lll"   },
   2977  1.1  mrg   { "__insn_sltih_u",         TILEPRO_INSN_SLTIH_U,     true,  "lll"   },
   2978  1.1  mrg   { "__insn_sne",             TILEPRO_INSN_SNE,         true,  "lll"   },
   2979  1.1  mrg   { "__insn_sneb",            TILEPRO_INSN_SNEB,        true,  "lll"   },
   2980  1.1  mrg   { "__insn_sneh",            TILEPRO_INSN_SNEH,        true,  "lll"   },
   2981  1.1  mrg   { "__insn_sra",             TILEPRO_INSN_SRA,         true,  "lll"   },
   2982  1.1  mrg   { "__insn_srab",            TILEPRO_INSN_SRAB,        true,  "lll"   },
   2983  1.1  mrg   { "__insn_srah",            TILEPRO_INSN_SRAH,        true,  "lll"   },
   2984  1.1  mrg   { "__insn_srai",            TILEPRO_INSN_SRA,         true,  "lll"   },
   2985  1.1  mrg   { "__insn_sraib",           TILEPRO_INSN_SRAIB,       true,  "lll"   },
   2986  1.1  mrg   { "__insn_sraih",           TILEPRO_INSN_SRAIH,       true,  "lll"   },
   2987  1.1  mrg   { "__insn_sub",             TILEPRO_INSN_SUB,         true,  "lll"   },
   2988  1.1  mrg   { "__insn_subb",            TILEPRO_INSN_SUBB,        true,  "lll"   },
   2989  1.1  mrg   { "__insn_subbs_u",         TILEPRO_INSN_SUBBS_U,     false, "lll"   },
   2990  1.1  mrg   { "__insn_subh",            TILEPRO_INSN_SUBH,        true,  "lll"   },
   2991  1.1  mrg   { "__insn_subhs",           TILEPRO_INSN_SUBHS,       false, "lll"   },
   2992  1.1  mrg   { "__insn_subs",            TILEPRO_INSN_SUBS,        false, "lll"   },
   2993  1.1  mrg   { "__insn_sw",              TILEPRO_INSN_SW,          false, "vpl"   },
   2994  1.1  mrg   { "__insn_tblidxb0",        TILEPRO_INSN_TBLIDXB0,    true,  "lll"   },
   2995  1.1  mrg   { "__insn_tblidxb1",        TILEPRO_INSN_TBLIDXB1,    true,  "lll"   },
   2996  1.1  mrg   { "__insn_tblidxb2",        TILEPRO_INSN_TBLIDXB2,    true,  "lll"   },
   2997  1.1  mrg   { "__insn_tblidxb3",        TILEPRO_INSN_TBLIDXB3,    true,  "lll"   },
   2998  1.1  mrg   { "__insn_tns",             TILEPRO_INSN_TNS,         false, "lp"    },
   2999  1.1  mrg   { "__insn_wh64",            TILEPRO_INSN_WH64,        false, "vp"    },
   3000  1.1  mrg   { "__insn_xor",             TILEPRO_INSN_XOR,         true,  "lll"   },
   3001  1.1  mrg   { "__insn_xori",            TILEPRO_INSN_XOR,         true,  "lll"   },
   3002  1.1  mrg   { "__tile_network_barrier", TILEPRO_NETWORK_BARRIER,  false, "v"     },
   3003  1.1  mrg   { "__tile_idn0_receive",    TILEPRO_IDN0_RECEIVE,     false, "l"     },
   3004  1.1  mrg   { "__tile_idn1_receive",    TILEPRO_IDN1_RECEIVE,     false, "l"     },
   3005  1.1  mrg   { "__tile_idn_send",        TILEPRO_IDN_SEND,         false, "vl"    },
   3006  1.1  mrg   { "__tile_sn_receive",      TILEPRO_SN_RECEIVE,       false, "l"     },
   3007  1.1  mrg   { "__tile_sn_send",         TILEPRO_SN_SEND,          false, "vl"    },
   3008  1.1  mrg   { "__tile_udn0_receive",    TILEPRO_UDN0_RECEIVE,     false, "l"     },
   3009  1.1  mrg   { "__tile_udn1_receive",    TILEPRO_UDN1_RECEIVE,     false, "l"     },
   3010  1.1  mrg   { "__tile_udn2_receive",    TILEPRO_UDN2_RECEIVE,     false, "l"     },
   3011  1.1  mrg   { "__tile_udn3_receive",    TILEPRO_UDN3_RECEIVE,     false, "l"     },
   3012  1.1  mrg   { "__tile_udn_send",        TILEPRO_UDN_SEND,         false, "vl"    },
   3013  1.1  mrg };
   3014  1.1  mrg 
   3015  1.1  mrg 
   3016  1.1  mrg /* Convert a character in a builtin type string to a tree type.  */
   3017  1.1  mrg static tree
   3018  1.1  mrg char_to_type (char c)
   3019  1.1  mrg {
   3020  1.1  mrg   static tree volatile_ptr_type_node = NULL;
   3021  1.1  mrg   static tree volatile_const_ptr_type_node = NULL;
   3022  1.1  mrg 
   3023  1.1  mrg   if (volatile_ptr_type_node == NULL)
   3024  1.1  mrg     {
   3025  1.1  mrg       volatile_ptr_type_node =
   3026  1.1  mrg 	build_pointer_type (build_qualified_type (void_type_node,
   3027  1.1  mrg 						  TYPE_QUAL_VOLATILE));
   3028  1.1  mrg       volatile_const_ptr_type_node =
   3029  1.1  mrg 	build_pointer_type (build_qualified_type (void_type_node,
   3030  1.1  mrg 						  TYPE_QUAL_CONST
   3031  1.1  mrg 						  | TYPE_QUAL_VOLATILE));
   3032  1.1  mrg     }
   3033  1.1  mrg 
   3034  1.1  mrg   switch (c)
   3035  1.1  mrg     {
   3036  1.1  mrg     case 'v':
   3037  1.1  mrg       return void_type_node;
   3038  1.1  mrg     case 'l':
   3039  1.1  mrg       return long_unsigned_type_node;
   3040  1.1  mrg     case 'p':
   3041  1.1  mrg       return volatile_ptr_type_node;
   3042  1.1  mrg     case 'k':
   3043  1.1  mrg       return volatile_const_ptr_type_node;
   3044  1.1  mrg     default:
   3045  1.1  mrg       gcc_unreachable ();
   3046  1.1  mrg     }
   3047  1.1  mrg }
   3048  1.1  mrg 
   3049  1.1  mrg 
   3050  1.1  mrg /* Implement TARGET_INIT_BUILTINS.  */
   3051  1.1  mrg static void
   3052  1.1  mrg tilepro_init_builtins (void)
   3053  1.1  mrg {
   3054  1.1  mrg   size_t i;
   3055  1.1  mrg 
   3056  1.1  mrg   for (i = 0; i < ARRAY_SIZE (tilepro_builtins); i++)
   3057  1.1  mrg     {
   3058  1.1  mrg       const struct tilepro_builtin_def *p = &tilepro_builtins[i];
   3059  1.1  mrg       tree ftype, ret_type, arg_type_list = void_list_node;
   3060  1.1  mrg       tree decl;
   3061  1.1  mrg       int j;
   3062  1.1  mrg 
   3063  1.1  mrg       for (j = strlen (p->type) - 1; j > 0; j--)
   3064  1.1  mrg 	{
   3065  1.1  mrg 	  arg_type_list =
   3066  1.1  mrg 	    tree_cons (NULL_TREE, char_to_type (p->type[j]), arg_type_list);
   3067  1.1  mrg 	}
   3068  1.1  mrg 
   3069  1.1  mrg       ret_type = char_to_type (p->type[0]);
   3070  1.1  mrg 
   3071  1.1  mrg       ftype = build_function_type (ret_type, arg_type_list);
   3072  1.1  mrg 
   3073  1.1  mrg       decl = add_builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
   3074  1.1  mrg 				   NULL, NULL);
   3075  1.1  mrg 
   3076  1.1  mrg       if (p->is_const)
   3077  1.1  mrg 	TREE_READONLY (decl) = 1;
   3078  1.1  mrg       TREE_NOTHROW (decl) = 1;
   3079  1.1  mrg 
   3080  1.1  mrg       if (tilepro_builtin_info[p->code].fndecl == NULL)
   3081  1.1  mrg 	tilepro_builtin_info[p->code].fndecl = decl;
   3082  1.1  mrg     }
   3083  1.1  mrg }
   3084  1.1  mrg 
   3085  1.1  mrg 
   3086  1.1  mrg /* Implement TARGET_EXPAND_BUILTIN.  */
   3087  1.1  mrg static rtx
   3088  1.1  mrg tilepro_expand_builtin (tree exp,
   3089  1.1  mrg 			rtx target,
   3090  1.1  mrg 			rtx subtarget ATTRIBUTE_UNUSED,
   3091  1.1  mrg 			machine_mode mode ATTRIBUTE_UNUSED,
   3092  1.1  mrg 			int ignore ATTRIBUTE_UNUSED)
   3093  1.1  mrg {
   3094  1.1  mrg #define MAX_BUILTIN_ARGS 4
   3095  1.1  mrg 
   3096  1.1  mrg   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   3097  1.1  mrg   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   3098  1.1  mrg   tree arg;
   3099  1.1  mrg   call_expr_arg_iterator iter;
   3100  1.1  mrg   enum insn_code icode;
   3101  1.1  mrg   rtx op[MAX_BUILTIN_ARGS + 1], pat;
   3102  1.1  mrg   int opnum;
   3103  1.1  mrg   bool nonvoid;
   3104  1.1  mrg   insn_gen_fn fn;
   3105  1.1  mrg 
   3106  1.1  mrg   if (fcode >= TILEPRO_BUILTIN_max)
   3107  1.1  mrg     internal_error ("bad builtin fcode");
   3108  1.1  mrg   icode = tilepro_builtin_info[fcode].icode;
   3109  1.1  mrg   if (icode == 0)
   3110  1.1  mrg     internal_error ("bad builtin icode");
   3111  1.1  mrg 
   3112  1.1  mrg   nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
   3113  1.1  mrg 
   3114  1.1  mrg   opnum = nonvoid;
   3115  1.1  mrg   FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
   3116  1.1  mrg   {
   3117  1.1  mrg     const struct insn_operand_data *insn_op;
   3118  1.1  mrg 
   3119  1.1  mrg     if (arg == error_mark_node)
   3120  1.1  mrg       return NULL_RTX;
   3121  1.1  mrg     if (opnum > MAX_BUILTIN_ARGS)
   3122  1.1  mrg       return NULL_RTX;
   3123  1.1  mrg 
   3124  1.1  mrg     insn_op = &insn_data[icode].operand[opnum];
   3125  1.1  mrg 
   3126  1.1  mrg     op[opnum] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
   3127  1.1  mrg 
   3128  1.1  mrg     if (!(*insn_op->predicate) (op[opnum], insn_op->mode))
   3129  1.1  mrg       op[opnum] = copy_to_mode_reg (insn_op->mode, op[opnum]);
   3130  1.1  mrg 
   3131  1.1  mrg     if (!(*insn_op->predicate) (op[opnum], insn_op->mode))
   3132  1.1  mrg       {
   3133  1.1  mrg 	/* We still failed to meet the predicate even after moving
   3134  1.1  mrg 	   into a register. Assume we needed an immediate.  */
   3135  1.1  mrg 	error_at (EXPR_LOCATION (exp),
   3136  1.1  mrg 		  "operand must be an immediate of the right size");
   3137  1.1  mrg 	return const0_rtx;
   3138  1.1  mrg       }
   3139  1.1  mrg 
   3140  1.1  mrg     opnum++;
   3141  1.1  mrg   }
   3142  1.1  mrg 
   3143  1.1  mrg   if (nonvoid)
   3144  1.1  mrg     {
   3145  1.1  mrg       machine_mode tmode = insn_data[icode].operand[0].mode;
   3146  1.1  mrg       if (!target
   3147  1.1  mrg 	  || GET_MODE (target) != tmode
   3148  1.1  mrg 	  || !(*insn_data[icode].operand[0].predicate) (target, tmode))
   3149  1.1  mrg 	target = gen_reg_rtx (tmode);
   3150  1.1  mrg       op[0] = target;
   3151  1.1  mrg     }
   3152  1.1  mrg 
   3153  1.1  mrg   fn = GEN_FCN (icode);
   3154  1.1  mrg   switch (opnum)
   3155  1.1  mrg     {
   3156  1.1  mrg     case 0:
   3157  1.1  mrg       pat = fn (NULL_RTX);
   3158  1.1  mrg       break;
   3159  1.1  mrg     case 1:
   3160  1.1  mrg       pat = fn (op[0]);
   3161  1.1  mrg       break;
   3162  1.1  mrg     case 2:
   3163  1.1  mrg       pat = fn (op[0], op[1]);
   3164  1.1  mrg       break;
   3165  1.1  mrg     case 3:
   3166  1.1  mrg       pat = fn (op[0], op[1], op[2]);
   3167  1.1  mrg       break;
   3168  1.1  mrg     case 4:
   3169  1.1  mrg       pat = fn (op[0], op[1], op[2], op[3]);
   3170  1.1  mrg       break;
   3171  1.1  mrg     case 5:
   3172  1.1  mrg       pat = fn (op[0], op[1], op[2], op[3], op[4]);
   3173  1.1  mrg       break;
   3174  1.1  mrg     default:
   3175  1.1  mrg       gcc_unreachable ();
   3176  1.1  mrg     }
   3177  1.1  mrg   if (!pat)
   3178  1.1  mrg     return NULL_RTX;
   3179  1.1  mrg 
   3180  1.1  mrg   /* If we are generating a prefetch, tell the scheduler not to move
   3181  1.1  mrg      it around.  */
   3182  1.1  mrg   if (GET_CODE (pat) == PREFETCH)
   3183  1.1  mrg     PREFETCH_SCHEDULE_BARRIER_P (pat) = true;
   3184  1.1  mrg 
   3185  1.1  mrg   emit_insn (pat);
   3186  1.1  mrg 
   3187  1.1  mrg   if (nonvoid)
   3188  1.1  mrg     return target;
   3189  1.1  mrg   else
   3190  1.1  mrg     return const0_rtx;
   3191  1.1  mrg }
   3192  1.1  mrg 
   3193  1.1  mrg 
   3194  1.1  mrg /* Implement TARGET_BUILTIN_DECL.  */
   3195  1.1  mrg static tree
   3196  1.1  mrg tilepro_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
   3197  1.1  mrg {
   3198  1.1  mrg   if (code >= TILEPRO_BUILTIN_max)
   3199  1.1  mrg     return error_mark_node;
   3200  1.1  mrg 
   3201  1.1  mrg   return tilepro_builtin_info[code].fndecl;
   3202  1.1  mrg }
   3203  1.1  mrg 
   3204  1.1  mrg 
   3206  1.1  mrg 
   3207  1.1  mrg /* Stack frames  */
   3208  1.1  mrg 
   3209  1.1  mrg /* Return whether REGNO needs to be saved in the stack frame.  */
   3210  1.1  mrg static bool
   3211  1.1  mrg need_to_save_reg (unsigned int regno)
   3212  1.1  mrg {
   3213  1.1  mrg   if (!call_used_or_fixed_reg_p (regno)
   3214  1.1  mrg       && df_regs_ever_live_p (regno))
   3215  1.1  mrg     return true;
   3216  1.1  mrg 
   3217  1.1  mrg   if (flag_pic
   3218  1.1  mrg       && (regno == PIC_OFFSET_TABLE_REGNUM
   3219  1.1  mrg 	  || regno == TILEPRO_PIC_TEXT_LABEL_REGNUM)
   3220  1.1  mrg       && (crtl->uses_pic_offset_table || crtl->saves_all_registers))
   3221  1.1  mrg     return true;
   3222  1.1  mrg 
   3223  1.1  mrg   if (crtl->calls_eh_return)
   3224  1.1  mrg     {
   3225  1.1  mrg       unsigned i;
   3226  1.1  mrg       for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
   3227  1.1  mrg 	{
   3228  1.1  mrg 	  if (regno == EH_RETURN_DATA_REGNO (i))
   3229  1.1  mrg 	    return true;
   3230  1.1  mrg 	}
   3231  1.1  mrg     }
   3232  1.1  mrg 
   3233  1.1  mrg   return false;
   3234  1.1  mrg }
   3235  1.1  mrg 
   3236  1.1  mrg 
   3237  1.1  mrg /* Return the size of the register savev area.  This function is only
   3238  1.1  mrg    correct starting with local register allocation */
   3239  1.1  mrg static int
   3240  1.1  mrg tilepro_saved_regs_size (void)
   3241  1.1  mrg {
   3242  1.1  mrg   int reg_save_size = 0;
   3243  1.1  mrg   int regno;
   3244  1.1  mrg   int offset_to_frame;
   3245  1.1  mrg   int align_mask;
   3246  1.1  mrg 
   3247  1.1  mrg   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   3248  1.1  mrg     if (need_to_save_reg (regno))
   3249  1.1  mrg       reg_save_size += UNITS_PER_WORD;
   3250  1.1  mrg 
   3251  1.1  mrg   /* Pad out the register save area if necessary to make
   3252  1.1  mrg      frame_pointer_rtx be as aligned as the stack pointer.  */
   3253  1.1  mrg   offset_to_frame = crtl->args.pretend_args_size + reg_save_size;
   3254  1.1  mrg   align_mask = (STACK_BOUNDARY / BITS_PER_UNIT) - 1;
   3255  1.1  mrg   reg_save_size += (-offset_to_frame) & align_mask;
   3256  1.1  mrg 
   3257  1.1  mrg   return reg_save_size;
   3258  1.1  mrg }
   3259  1.1  mrg 
   3260  1.1  mrg 
   3261  1.1  mrg /* Round up frame size SIZE.  */
   3262  1.1  mrg static int
   3263  1.1  mrg round_frame_size (int size)
   3264  1.1  mrg {
   3265  1.1  mrg   return ((size + STACK_BOUNDARY / BITS_PER_UNIT - 1)
   3266  1.1  mrg 	  & -STACK_BOUNDARY / BITS_PER_UNIT);
   3267  1.1  mrg }
   3268  1.1  mrg 
   3269  1.1  mrg 
   3270  1.1  mrg /* Emit a store in the stack frame to save REGNO at address ADDR, and
   3271  1.1  mrg    emit the corresponding REG_CFA_OFFSET note described by CFA and
   3272  1.1  mrg    CFA_OFFSET.  Return the emitted insn.  */
   3273  1.1  mrg static rtx
   3274  1.1  mrg frame_emit_store (int regno, int regno_note, rtx addr, rtx cfa,
   3275  1.1  mrg 		  int cfa_offset)
   3276  1.1  mrg {
   3277  1.1  mrg   rtx reg = gen_rtx_REG (Pmode, regno);
   3278  1.1  mrg   rtx mem = gen_frame_mem (Pmode, addr);
   3279  1.1  mrg   rtx mov = gen_movsi (mem, reg);
   3280  1.1  mrg 
   3281  1.1  mrg   /* Describe what just happened in a way that dwarf understands.  We
   3282  1.1  mrg      use temporary registers to hold the address to make scheduling
   3283  1.1  mrg      easier, and use the REG_CFA_OFFSET to describe the address as an
   3284  1.1  mrg      offset from the CFA.  */
   3285  1.1  mrg   rtx reg_note = gen_rtx_REG (Pmode, regno_note);
   3286  1.1  mrg   rtx cfa_relative_addr = gen_rtx_PLUS (Pmode, cfa, gen_int_si (cfa_offset));
   3287  1.1  mrg   rtx cfa_relative_mem = gen_frame_mem (Pmode, cfa_relative_addr);
   3288  1.1  mrg   rtx real = gen_rtx_SET (cfa_relative_mem, reg_note);
   3289  1.1  mrg   add_reg_note (mov, REG_CFA_OFFSET, real);
   3290  1.1  mrg 
   3291  1.1  mrg   return emit_insn (mov);
   3292  1.1  mrg }
   3293  1.1  mrg 
   3294  1.1  mrg 
   3295  1.1  mrg /* Emit a load in the stack frame to load REGNO from address ADDR.
   3296  1.1  mrg    Add a REG_CFA_RESTORE note to CFA_RESTORES if CFA_RESTORES is
   3297  1.1  mrg    non-null.  Return the emitted insn.  */
   3298  1.1  mrg static rtx_insn *
   3299  1.1  mrg frame_emit_load (int regno, rtx addr, rtx *cfa_restores)
   3300  1.1  mrg {
   3301  1.1  mrg   rtx reg = gen_rtx_REG (Pmode, regno);
   3302  1.1  mrg   rtx mem = gen_frame_mem (Pmode, addr);
   3303  1.1  mrg   if (cfa_restores)
   3304  1.1  mrg     *cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, *cfa_restores);
   3305  1.1  mrg   return emit_insn (gen_movsi (reg, mem));
   3306  1.1  mrg }
   3307  1.1  mrg 
   3308  1.1  mrg 
   3309  1.1  mrg /* Helper function to set RTX_FRAME_RELATED_P on instructions,
   3310  1.1  mrg    including sequences.  */
   3311  1.1  mrg static rtx_insn *
   3312  1.1  mrg set_frame_related_p (void)
   3313  1.1  mrg {
   3314  1.1  mrg   rtx_insn *seq = get_insns ();
   3315  1.1  mrg   rtx_insn *insn;
   3316  1.1  mrg 
   3317  1.1  mrg   end_sequence ();
   3318  1.1  mrg 
   3319  1.1  mrg   if (!seq)
   3320  1.1  mrg     return NULL;
   3321  1.1  mrg 
   3322  1.1  mrg   if (INSN_P (seq))
   3323  1.1  mrg     {
   3324  1.1  mrg       insn = seq;
   3325  1.1  mrg       while (insn != NULL_RTX)
   3326  1.1  mrg 	{
   3327  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
   3328  1.1  mrg 	  insn = NEXT_INSN (insn);
   3329  1.1  mrg 	}
   3330  1.1  mrg       seq = emit_insn (seq);
   3331  1.1  mrg     }
   3332  1.1  mrg   else
   3333  1.1  mrg     {
   3334  1.1  mrg       seq = emit_insn (seq);
   3335  1.1  mrg       RTX_FRAME_RELATED_P (seq) = 1;
   3336  1.1  mrg     }
   3337  1.1  mrg   return seq;
   3338  1.1  mrg }
   3339  1.1  mrg 
   3340  1.1  mrg 
   3341  1.1  mrg #define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
   3342  1.1  mrg 
   3343  1.1  mrg /* This emits code for 'sp += offset'.
   3344  1.1  mrg 
   3345  1.1  mrg    The ABI only allows us to modify 'sp' in a single 'addi' or
   3346  1.1  mrg    'addli', so the backtracer understands it. Larger amounts cannot
   3347  1.1  mrg    use those instructions, so are added by placing the offset into a
   3348  1.1  mrg    large register and using 'add'.
   3349  1.1  mrg 
   3350  1.1  mrg    This happens after reload, so we need to expand it ourselves.  */
   3351  1.1  mrg static rtx_insn *
   3352  1.1  mrg emit_sp_adjust (int offset, int *next_scratch_regno, bool frame_related,
   3353  1.1  mrg 		rtx reg_notes)
   3354  1.1  mrg {
   3355  1.1  mrg   rtx to_add;
   3356  1.1  mrg   rtx imm_rtx = gen_int_si (offset);
   3357  1.1  mrg 
   3358  1.1  mrg   rtx_insn *insn;
   3359  1.1  mrg   if (satisfies_constraint_J (imm_rtx))
   3360  1.1  mrg     {
   3361  1.1  mrg       /* We can add this using a single addi or addli.  */
   3362  1.1  mrg       to_add = imm_rtx;
   3363  1.1  mrg     }
   3364  1.1  mrg   else
   3365  1.1  mrg     {
   3366  1.1  mrg       rtx tmp = gen_rtx_REG (Pmode, (*next_scratch_regno)--);
   3367  1.1  mrg       tilepro_expand_set_const32 (tmp, imm_rtx);
   3368  1.1  mrg       to_add = tmp;
   3369  1.1  mrg     }
   3370  1.1  mrg 
   3371  1.1  mrg   /* Actually adjust the stack pointer.  */
   3372  1.1  mrg   insn = emit_insn (gen_sp_adjust (stack_pointer_rtx, stack_pointer_rtx,
   3373  1.1  mrg 				   to_add));
   3374  1.1  mrg   REG_NOTES (insn) = reg_notes;
   3375  1.1  mrg 
   3376  1.1  mrg   /* Describe what just happened in a way that dwarf understands.  */
   3377  1.1  mrg   if (frame_related)
   3378  1.1  mrg     {
   3379  1.1  mrg       rtx real = gen_rtx_SET (stack_pointer_rtx,
   3380  1.1  mrg 			      gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   3381  1.1  mrg 					    imm_rtx));
   3382  1.1  mrg       RTX_FRAME_RELATED_P (insn) = 1;
   3383  1.1  mrg       add_reg_note (insn, REG_CFA_ADJUST_CFA, real);
   3384  1.1  mrg     }
   3385  1.1  mrg 
   3386  1.1  mrg   return insn;
   3387  1.1  mrg }
   3388  1.1  mrg 
   3389  1.1  mrg 
   3390  1.1  mrg /* Return whether the current function is leaf.  This takes into
   3391  1.1  mrg    account whether the function calls tls_get_addr.  */
   3392  1.1  mrg static bool
   3393  1.1  mrg tilepro_current_function_is_leaf (void)
   3394  1.1  mrg {
   3395  1.1  mrg   return crtl->is_leaf && !cfun->machine->calls_tls_get_addr;
   3396  1.1  mrg }
   3397  1.1  mrg 
   3398  1.1  mrg 
   3399  1.1  mrg /* Return the frame size.  */
   3400  1.1  mrg static int
   3401  1.1  mrg compute_total_frame_size (void)
   3402  1.1  mrg {
   3403  1.1  mrg   int total_size = (get_frame_size () + tilepro_saved_regs_size ()
   3404  1.1  mrg 		    + crtl->outgoing_args_size
   3405  1.1  mrg 		    + crtl->args.pretend_args_size);
   3406  1.1  mrg 
   3407  1.1  mrg   if (!tilepro_current_function_is_leaf () || cfun->calls_alloca)
   3408  1.1  mrg     {
   3409  1.1  mrg       /* Make room for save area in callee.  */
   3410  1.1  mrg       total_size += STACK_POINTER_OFFSET;
   3411  1.1  mrg     }
   3412  1.1  mrg 
   3413  1.1  mrg   return round_frame_size (total_size);
   3414  1.1  mrg }
   3415  1.1  mrg 
   3416  1.1  mrg 
   3417  1.1  mrg /* Return nonzero if this function is known to have a null epilogue.
   3418  1.1  mrg    This allows the optimizer to omit jumps to jumps if no stack was
   3419  1.1  mrg    created.  */
   3420  1.1  mrg bool
   3421  1.1  mrg tilepro_can_use_return_insn_p (void)
   3422  1.1  mrg {
   3423  1.1  mrg   return (reload_completed
   3424  1.1  mrg 	  && cfun->static_chain_decl == 0
   3425  1.1  mrg 	  && compute_total_frame_size () == 0
   3426  1.1  mrg 	  && tilepro_current_function_is_leaf ()
   3427  1.1  mrg 	  && !crtl->profile && !df_regs_ever_live_p (TILEPRO_LINK_REGNUM));
   3428  1.1  mrg }
   3429  1.1  mrg 
   3430  1.1  mrg 
   3431  1.1  mrg /* Returns an rtx for a stack slot at 'FP + offset_from_fp'.  If there
   3432  1.1  mrg    is a frame pointer, it computes the value relative to
   3433  1.1  mrg    that. Otherwise it uses the stack pointer.  */
   3434  1.1  mrg static rtx
   3435  1.1  mrg compute_frame_addr (int offset_from_fp, int *next_scratch_regno)
   3436  1.1  mrg {
   3437  1.1  mrg   rtx base_reg_rtx, tmp_reg_rtx, offset_rtx;
   3438  1.1  mrg   int offset_from_base;
   3439  1.1  mrg 
   3440  1.1  mrg   if (frame_pointer_needed)
   3441  1.1  mrg     {
   3442  1.1  mrg       base_reg_rtx = hard_frame_pointer_rtx;
   3443  1.1  mrg       offset_from_base = offset_from_fp;
   3444  1.1  mrg     }
   3445  1.1  mrg   else
   3446  1.1  mrg     {
   3447  1.1  mrg       int offset_from_sp = compute_total_frame_size () + offset_from_fp;
   3448  1.1  mrg       base_reg_rtx = stack_pointer_rtx;
   3449  1.1  mrg       offset_from_base = offset_from_sp;
   3450  1.1  mrg     }
   3451  1.1  mrg 
   3452  1.1  mrg   if (offset_from_base == 0)
   3453  1.1  mrg     return base_reg_rtx;
   3454  1.1  mrg 
   3455  1.1  mrg   /* Compute the new value of the stack pointer.  */
   3456  1.1  mrg   tmp_reg_rtx = gen_rtx_REG (Pmode, (*next_scratch_regno)--);
   3457  1.1  mrg   offset_rtx = gen_int_si (offset_from_base);
   3458  1.1  mrg 
   3459  1.1  mrg   if (!tilepro_expand_addsi (tmp_reg_rtx, base_reg_rtx, offset_rtx))
   3460  1.1  mrg     {
   3461  1.1  mrg       emit_insn (gen_rtx_SET (tmp_reg_rtx,
   3462  1.1  mrg 			      gen_rtx_PLUS (Pmode, base_reg_rtx,
   3463  1.1  mrg 					    offset_rtx)));
   3464  1.1  mrg     }
   3465  1.1  mrg 
   3466  1.1  mrg   return tmp_reg_rtx;
   3467  1.1  mrg }
   3468  1.1  mrg 
   3469  1.1  mrg 
   3470  1.1  mrg /* The stack frame looks like this:
   3471  1.1  mrg          +-------------+
   3472  1.1  mrg          |    ...      |
   3473  1.1  mrg          |  incoming   |
   3474  1.1  mrg          | stack args  |
   3475  1.1  mrg    AP -> +-------------+
   3476  1.1  mrg          | caller's HFP|
   3477  1.1  mrg          +-------------+
   3478  1.1  mrg          | lr save     |
   3479  1.1  mrg   HFP -> +-------------+
   3480  1.1  mrg          |  var args   |
   3481  1.1  mrg          |  reg save   | crtl->args.pretend_args_size bytes
   3482  1.1  mrg          +-------------+
   3483  1.1  mrg          |    ...      |
   3484  1.1  mrg          | saved regs  | tilepro_saved_regs_size() bytes
   3485  1.1  mrg    FP -> +-------------+
   3486  1.1  mrg          |    ...      |
   3487  1.1  mrg          |   vars      | get_frame_size() bytes
   3488  1.1  mrg          +-------------+
   3489  1.1  mrg          |    ...      |
   3490  1.1  mrg          |  outgoing   |
   3491  1.1  mrg          |  stack args | crtl->outgoing_args_size bytes
   3492  1.1  mrg          +-------------+
   3493  1.1  mrg          | HFP         | 4 bytes (only here if nonleaf / alloca)
   3494  1.1  mrg          +-------------+
   3495  1.1  mrg          | callee lr   | 4 bytes (only here if nonleaf / alloca)
   3496  1.1  mrg          | save        |
   3497  1.1  mrg    SP -> +-------------+
   3498  1.1  mrg 
   3499  1.1  mrg   HFP == incoming SP.
   3500  1.1  mrg 
   3501  1.1  mrg   For functions with a frame larger than 32767 bytes, or which use
   3502  1.1  mrg   alloca (), r52 is used as a frame pointer.  Otherwise there is no
   3503  1.1  mrg   frame pointer.
   3504  1.1  mrg 
   3505  1.1  mrg   FP is saved at SP+4 before calling a subroutine so the
   3506  1.1  mrg   callee can chain.  */
   3507  1.1  mrg void
   3508  1.1  mrg tilepro_expand_prologue (void)
   3509  1.1  mrg {
   3510  1.1  mrg #define ROUND_ROBIN_SIZE 4
   3511  1.1  mrg   /* We round-robin through four scratch registers to hold temporary
   3512  1.1  mrg      addresses for saving registers, to make instruction scheduling
   3513  1.1  mrg      easier.  */
   3514  1.1  mrg   rtx reg_save_addr[ROUND_ROBIN_SIZE] = {
   3515  1.1  mrg     NULL_RTX, NULL_RTX, NULL_RTX, NULL_RTX
   3516  1.1  mrg   };
   3517  1.1  mrg   rtx insn, cfa;
   3518  1.1  mrg   unsigned int which_scratch;
   3519  1.1  mrg   int offset, start_offset, regno;
   3520  1.1  mrg 
   3521  1.1  mrg   /* A register that holds a copy of the incoming fp.  */
   3522  1.1  mrg   int fp_copy_regno = -1;
   3523  1.1  mrg 
   3524  1.1  mrg   /* A register that holds a copy of the incoming sp.  */
   3525  1.1  mrg   int sp_copy_regno = -1;
   3526  1.1  mrg 
   3527  1.1  mrg   /* Next scratch register number to hand out (postdecrementing).  */
   3528  1.1  mrg   int next_scratch_regno = 29;
   3529  1.1  mrg 
   3530  1.1  mrg   int total_size = compute_total_frame_size ();
   3531  1.1  mrg 
   3532  1.1  mrg   if (flag_stack_usage_info)
   3533  1.1  mrg     current_function_static_stack_size = total_size;
   3534  1.1  mrg 
   3535  1.1  mrg   /* Save lr first in its special location because code after this
   3536  1.1  mrg      might use the link register as a scratch register.  */
   3537  1.1  mrg   if (df_regs_ever_live_p (TILEPRO_LINK_REGNUM) || crtl->calls_eh_return)
   3538  1.1  mrg     {
   3539  1.1  mrg       FRP (frame_emit_store (TILEPRO_LINK_REGNUM, TILEPRO_LINK_REGNUM,
   3540  1.1  mrg 			     stack_pointer_rtx, stack_pointer_rtx, 0));
   3541  1.1  mrg       emit_insn (gen_blockage ());
   3542  1.1  mrg     }
   3543  1.1  mrg 
   3544  1.1  mrg   if (total_size == 0)
   3545  1.1  mrg     {
   3546  1.1  mrg       /* Load the PIC register if needed.  */
   3547  1.1  mrg       if (flag_pic && crtl->uses_pic_offset_table)
   3548  1.1  mrg 	load_pic_register (false);
   3549  1.1  mrg 
   3550  1.1  mrg       return;
   3551  1.1  mrg     }
   3552  1.1  mrg 
   3553  1.1  mrg   cfa = stack_pointer_rtx;
   3554  1.1  mrg 
   3555  1.1  mrg   if (frame_pointer_needed)
   3556  1.1  mrg     {
   3557  1.1  mrg       fp_copy_regno = next_scratch_regno--;
   3558  1.1  mrg 
   3559  1.1  mrg       /* Copy the old frame pointer aside so we can save it later.  */
   3560  1.1  mrg       insn = FRP (emit_move_insn (gen_rtx_REG (word_mode, fp_copy_regno),
   3561  1.1  mrg 				  hard_frame_pointer_rtx));
   3562  1.1  mrg       add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX);
   3563  1.1  mrg 
   3564  1.1  mrg       /* Set up the frame pointer.  */
   3565  1.1  mrg       insn = FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
   3566  1.1  mrg       add_reg_note (insn, REG_CFA_DEF_CFA, hard_frame_pointer_rtx);
   3567  1.1  mrg       cfa = hard_frame_pointer_rtx;
   3568  1.1  mrg       REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
   3569  1.1  mrg 
   3570  1.1  mrg       /* fp holds a copy of the incoming sp, in case we need to store
   3571  1.1  mrg          it.  */
   3572  1.1  mrg       sp_copy_regno = HARD_FRAME_POINTER_REGNUM;
   3573  1.1  mrg     }
   3574  1.1  mrg   else if (!tilepro_current_function_is_leaf ())
   3575  1.1  mrg     {
   3576  1.1  mrg       /* Copy the old stack pointer aside so we can save it later.  */
   3577  1.1  mrg       sp_copy_regno = next_scratch_regno--;
   3578  1.1  mrg       emit_move_insn (gen_rtx_REG (Pmode, sp_copy_regno),
   3579  1.1  mrg 		      stack_pointer_rtx);
   3580  1.1  mrg     }
   3581  1.1  mrg 
   3582  1.1  mrg   if (tilepro_current_function_is_leaf ())
   3583  1.1  mrg     {
   3584  1.1  mrg       /* No need to store chain pointer to caller's frame.  */
   3585  1.1  mrg       emit_sp_adjust (-total_size, &next_scratch_regno,
   3586  1.1  mrg 		      !frame_pointer_needed, NULL_RTX);
   3587  1.1  mrg     }
   3588  1.1  mrg   else
   3589  1.1  mrg     {
   3590  1.1  mrg       /* Save the frame pointer (incoming sp value) to support
   3591  1.1  mrg          backtracing.  First we need to create an rtx with the store
   3592  1.1  mrg          address.  */
   3593  1.1  mrg       rtx chain_addr = gen_rtx_REG (Pmode, next_scratch_regno--);
   3594  1.1  mrg       rtx size_rtx = gen_int_si (-(total_size - UNITS_PER_WORD));
   3595  1.1  mrg 
   3596  1.1  mrg       if (add_operand (size_rtx, Pmode))
   3597  1.1  mrg 	{
   3598  1.1  mrg 	  /* Expose more parallelism by computing this value from the
   3599  1.1  mrg 	     original stack pointer, not the one after we have pushed
   3600  1.1  mrg 	     the frame.  */
   3601  1.1  mrg 	  rtx p = gen_rtx_PLUS (Pmode, stack_pointer_rtx, size_rtx);
   3602  1.1  mrg 	  emit_insn (gen_rtx_SET (chain_addr, p));
   3603  1.1  mrg 	  emit_sp_adjust (-total_size, &next_scratch_regno,
   3604  1.1  mrg 			  !frame_pointer_needed, NULL_RTX);
   3605  1.1  mrg 	}
   3606  1.1  mrg       else
   3607  1.1  mrg 	{
   3608  1.1  mrg 	  /* The stack frame is large, so just store the incoming sp
   3609  1.1  mrg 	     value at *(new_sp + UNITS_PER_WORD).  */
   3610  1.1  mrg 	  rtx p;
   3611  1.1  mrg 	  emit_sp_adjust (-total_size, &next_scratch_regno,
   3612  1.1  mrg 			  !frame_pointer_needed, NULL_RTX);
   3613  1.1  mrg 	  p = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   3614  1.1  mrg 			    GEN_INT (UNITS_PER_WORD));
   3615  1.1  mrg 	  emit_insn (gen_rtx_SET (chain_addr, p));
   3616  1.1  mrg 	}
   3617  1.1  mrg 
   3618  1.1  mrg       /* Save our frame pointer for backtrace chaining.  */
   3619  1.1  mrg       emit_insn (gen_movsi (gen_frame_mem (SImode, chain_addr),
   3620  1.1  mrg 			    gen_rtx_REG (SImode, sp_copy_regno)));
   3621  1.1  mrg     }
   3622  1.1  mrg 
   3623  1.1  mrg   /* Compute where to start storing registers we need to save.  */
   3624  1.1  mrg   start_offset = -crtl->args.pretend_args_size - UNITS_PER_WORD;
   3625  1.1  mrg   offset = start_offset;
   3626  1.1  mrg 
   3627  1.1  mrg   /* Store all registers that need saving.  */
   3628  1.1  mrg   which_scratch = 0;
   3629  1.1  mrg   for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
   3630  1.1  mrg     if (need_to_save_reg (regno))
   3631  1.1  mrg       {
   3632  1.1  mrg 	rtx r = reg_save_addr[which_scratch];
   3633  1.1  mrg 	int from_regno;
   3634  1.1  mrg 	int cfa_offset = frame_pointer_needed ? offset : total_size + offset;
   3635  1.1  mrg 
   3636  1.1  mrg 	if (r == NULL_RTX)
   3637  1.1  mrg 	  {
   3638  1.1  mrg 	    rtx p = compute_frame_addr (offset, &next_scratch_regno);
   3639  1.1  mrg 	    r = gen_rtx_REG (word_mode, next_scratch_regno--);
   3640  1.1  mrg 	    reg_save_addr[which_scratch] = r;
   3641  1.1  mrg 
   3642  1.1  mrg 	    emit_insn (gen_rtx_SET (r, p));
   3643  1.1  mrg 	  }
   3644  1.1  mrg 	else
   3645  1.1  mrg 	  {
   3646  1.1  mrg 	    /* Advance to the next stack slot to store this register.  */
   3647  1.1  mrg 	    int stride = ROUND_ROBIN_SIZE * -UNITS_PER_WORD;
   3648  1.1  mrg 	    rtx p = gen_rtx_PLUS (Pmode, r, GEN_INT (stride));
   3649  1.1  mrg 	    emit_insn (gen_rtx_SET (r, p));
   3650  1.1  mrg 	  }
   3651  1.1  mrg 
   3652  1.1  mrg 	/* Save this register to the stack (but use the old fp value
   3653  1.1  mrg 	   we copied aside if appropriate).  */
   3654  1.1  mrg 	from_regno = (fp_copy_regno >= 0
   3655  1.1  mrg 		      && regno ==
   3656  1.1  mrg 		      HARD_FRAME_POINTER_REGNUM) ? fp_copy_regno : regno;
   3657  1.1  mrg 	FRP (frame_emit_store (from_regno, regno, r, cfa, cfa_offset));
   3658  1.1  mrg 
   3659  1.1  mrg 	offset -= UNITS_PER_WORD;
   3660  1.1  mrg 	which_scratch = (which_scratch + 1) % ROUND_ROBIN_SIZE;
   3661  1.1  mrg       }
   3662  1.1  mrg 
   3663  1.1  mrg   /* If profiling, force that to happen after the frame is set up.  */
   3664  1.1  mrg   if (crtl->profile)
   3665  1.1  mrg     emit_insn (gen_blockage ());
   3666  1.1  mrg 
   3667  1.1  mrg   /* Load the PIC register if needed.  */
   3668  1.1  mrg   if (flag_pic && crtl->uses_pic_offset_table)
   3669  1.1  mrg     load_pic_register (false);
   3670  1.1  mrg }
   3671  1.1  mrg 
   3672  1.1  mrg 
   3673  1.1  mrg /* Implement the epilogue and sibcall_epilogue patterns.  SIBCALL_P is
   3674  1.1  mrg    true for a sibcall_epilogue pattern, and false for an epilogue
   3675  1.1  mrg    pattern.  */
   3676  1.1  mrg void
   3677  1.1  mrg tilepro_expand_epilogue (bool sibcall_p)
   3678  1.1  mrg {
   3679  1.1  mrg   /* We round-robin through four scratch registers to hold temporary
   3680  1.1  mrg      addresses for saving registers, to make instruction scheduling
   3681  1.1  mrg      easier.  */
   3682  1.1  mrg   rtx reg_save_addr[ROUND_ROBIN_SIZE] = {
   3683  1.1  mrg     NULL_RTX, NULL_RTX, NULL_RTX, NULL_RTX
   3684  1.1  mrg   };
   3685  1.1  mrg   rtx_insn *last_insn, *insn;
   3686  1.1  mrg   unsigned int which_scratch;
   3687  1.1  mrg   int offset, start_offset, regno;
   3688  1.1  mrg   rtx cfa_restores = NULL_RTX;
   3689  1.1  mrg 
   3690  1.1  mrg   /* A register that holds a copy of the incoming fp.  */
   3691  1.1  mrg   int fp_copy_regno = -1;
   3692  1.1  mrg 
   3693  1.1  mrg   /* Next scratch register number to hand out (postdecrementing).  */
   3694  1.1  mrg   int next_scratch_regno = 29;
   3695  1.1  mrg 
   3696  1.1  mrg   int total_size = compute_total_frame_size ();
   3697  1.1  mrg 
   3698  1.1  mrg   last_insn = get_last_insn ();
   3699  1.1  mrg 
   3700  1.1  mrg   /* Load lr first since we are going to need it first.  */
   3701  1.1  mrg   insn = NULL;
   3702  1.1  mrg   if (df_regs_ever_live_p (TILEPRO_LINK_REGNUM))
   3703  1.1  mrg     {
   3704  1.1  mrg       insn = frame_emit_load (TILEPRO_LINK_REGNUM,
   3705  1.1  mrg 			      compute_frame_addr (0, &next_scratch_regno),
   3706  1.1  mrg 			      &cfa_restores);
   3707  1.1  mrg     }
   3708  1.1  mrg 
   3709  1.1  mrg   if (total_size == 0)
   3710  1.1  mrg     {
   3711  1.1  mrg       if (insn)
   3712  1.1  mrg 	{
   3713  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
   3714  1.1  mrg 	  REG_NOTES (insn) = cfa_restores;
   3715  1.1  mrg 	}
   3716  1.1  mrg       goto done;
   3717  1.1  mrg     }
   3718  1.1  mrg 
   3719  1.1  mrg   /* Compute where to start restoring registers.  */
   3720  1.1  mrg   start_offset = -crtl->args.pretend_args_size - UNITS_PER_WORD;
   3721  1.1  mrg   offset = start_offset;
   3722  1.1  mrg 
   3723  1.1  mrg   if (frame_pointer_needed)
   3724  1.1  mrg     fp_copy_regno = next_scratch_regno--;
   3725  1.1  mrg 
   3726  1.1  mrg   /* Restore all callee-saved registers.  */
   3727  1.1  mrg   which_scratch = 0;
   3728  1.1  mrg   for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
   3729  1.1  mrg     if (need_to_save_reg (regno))
   3730  1.1  mrg       {
   3731  1.1  mrg 	rtx r = reg_save_addr[which_scratch];
   3732  1.1  mrg 	if (r == NULL_RTX)
   3733  1.1  mrg 	  {
   3734  1.1  mrg 	    r = compute_frame_addr (offset, &next_scratch_regno);
   3735  1.1  mrg 	    reg_save_addr[which_scratch] = r;
   3736  1.1  mrg 	  }
   3737  1.1  mrg 	else
   3738  1.1  mrg 	  {
   3739  1.1  mrg 	    /* Advance to the next stack slot to store this
   3740  1.1  mrg 	       register.  */
   3741  1.1  mrg 	    int stride = ROUND_ROBIN_SIZE * -UNITS_PER_WORD;
   3742  1.1  mrg 	    rtx p = gen_rtx_PLUS (Pmode, r, GEN_INT (stride));
   3743  1.1  mrg 	    emit_insn (gen_rtx_SET (r, p));
   3744  1.1  mrg 	  }
   3745  1.1  mrg 
   3746  1.1  mrg 	if (fp_copy_regno >= 0 && regno == HARD_FRAME_POINTER_REGNUM)
   3747  1.1  mrg 	  frame_emit_load (fp_copy_regno, r, NULL);
   3748  1.1  mrg 	else
   3749  1.1  mrg 	  frame_emit_load (regno, r, &cfa_restores);
   3750  1.1  mrg 
   3751  1.1  mrg 	offset -= UNITS_PER_WORD;
   3752  1.1  mrg 	which_scratch = (which_scratch + 1) % ROUND_ROBIN_SIZE;
   3753  1.1  mrg       }
   3754  1.1  mrg 
   3755  1.1  mrg   if (!tilepro_current_function_is_leaf ())
   3756  1.1  mrg     cfa_restores =
   3757  1.1  mrg       alloc_reg_note (REG_CFA_RESTORE, stack_pointer_rtx, cfa_restores);
   3758  1.1  mrg 
   3759  1.1  mrg   emit_insn (gen_blockage ());
   3760  1.1  mrg 
   3761  1.1  mrg   if (frame_pointer_needed)
   3762  1.1  mrg     {
   3763  1.1  mrg       /* Restore the old stack pointer by copying from the frame
   3764  1.1  mrg          pointer.  */
   3765  1.1  mrg       insn = emit_insn (gen_sp_restore (stack_pointer_rtx,
   3766  1.1  mrg 					hard_frame_pointer_rtx));
   3767  1.1  mrg       RTX_FRAME_RELATED_P (insn) = 1;
   3768  1.1  mrg       REG_NOTES (insn) = cfa_restores;
   3769  1.1  mrg       add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
   3770  1.1  mrg     }
   3771  1.1  mrg   else
   3772  1.1  mrg     {
   3773  1.1  mrg       insn = emit_sp_adjust (total_size, &next_scratch_regno, true,
   3774  1.1  mrg 			     cfa_restores);
   3775  1.1  mrg     }
   3776  1.1  mrg 
   3777  1.1  mrg   if (crtl->calls_eh_return)
   3778  1.1  mrg     emit_insn (gen_sp_adjust (stack_pointer_rtx, stack_pointer_rtx,
   3779  1.1  mrg 			      EH_RETURN_STACKADJ_RTX));
   3780  1.1  mrg 
   3781  1.1  mrg   /* Restore the old frame pointer.  */
   3782  1.1  mrg   if (frame_pointer_needed)
   3783  1.1  mrg     {
   3784  1.1  mrg       insn = emit_move_insn (hard_frame_pointer_rtx,
   3785  1.1  mrg 			     gen_rtx_REG (Pmode, fp_copy_regno));
   3786  1.1  mrg       add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
   3787  1.1  mrg     }
   3788  1.1  mrg 
   3789  1.1  mrg   /* Mark the pic registers as live outside of the function.  */
   3790  1.1  mrg   if (flag_pic)
   3791  1.1  mrg     {
   3792  1.1  mrg       emit_use (cfun->machine->text_label_rtx);
   3793  1.1  mrg       emit_use (cfun->machine->got_rtx);
   3794  1.1  mrg     }
   3795  1.1  mrg 
   3796  1.1  mrg done:
   3797  1.1  mrg   if (!sibcall_p)
   3798  1.1  mrg     {
   3799  1.1  mrg       /* Emit the actual 'return' instruction.  */
   3800  1.1  mrg       emit_jump_insn (gen__return ());
   3801  1.1  mrg     }
   3802  1.1  mrg   else
   3803  1.1  mrg     {
   3804  1.1  mrg       emit_use (gen_rtx_REG (Pmode, TILEPRO_LINK_REGNUM));
   3805  1.1  mrg     }
   3806  1.1  mrg 
   3807  1.1  mrg   /* Mark all insns we just emitted as frame-related.  */
   3808  1.1  mrg   for (; last_insn != NULL_RTX; last_insn = next_insn (last_insn))
   3809  1.1  mrg     RTX_FRAME_RELATED_P (last_insn) = 1;
   3810  1.1  mrg }
   3811  1.1  mrg 
   3812  1.1  mrg #undef ROUND_ROBIN_SIZE
   3813  1.1  mrg 
   3814  1.1  mrg 
   3815  1.1  mrg /* Implement INITIAL_ELIMINATION_OFFSET.  */
   3816  1.1  mrg int
   3817  1.1  mrg tilepro_initial_elimination_offset (int from, int to)
   3818  1.1  mrg {
   3819  1.1  mrg   int total_size = compute_total_frame_size ();
   3820  1.1  mrg 
   3821  1.1  mrg   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
   3822  1.1  mrg     {
   3823  1.1  mrg       return (total_size - crtl->args.pretend_args_size
   3824  1.1  mrg 	      - tilepro_saved_regs_size ());
   3825  1.1  mrg     }
   3826  1.1  mrg   else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
   3827  1.1  mrg     {
   3828  1.1  mrg       return -(crtl->args.pretend_args_size + tilepro_saved_regs_size ());
   3829  1.1  mrg     }
   3830  1.1  mrg   else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
   3831  1.1  mrg     {
   3832  1.1  mrg       return STACK_POINTER_OFFSET + total_size;
   3833  1.1  mrg     }
   3834  1.1  mrg   else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
   3835  1.1  mrg     {
   3836  1.1  mrg       return STACK_POINTER_OFFSET;
   3837  1.1  mrg     }
   3838  1.1  mrg   else
   3839  1.1  mrg     gcc_unreachable ();
   3840  1.1  mrg }
   3841  1.1  mrg 
   3842  1.1  mrg 
   3843  1.1  mrg /* Return an RTX indicating where the return address to the
   3844  1.1  mrg    calling function can be found.  */
   3845  1.1  mrg rtx
   3846  1.1  mrg tilepro_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
   3847  1.1  mrg {
   3848  1.1  mrg   if (count != 0)
   3849  1.1  mrg     return const0_rtx;
   3850  1.1  mrg 
   3851  1.1  mrg   return get_hard_reg_initial_val (Pmode, TILEPRO_LINK_REGNUM);
   3852  1.1  mrg }
   3853  1.1  mrg 
   3854  1.1  mrg 
   3855  1.1  mrg /* Implement EH_RETURN_HANDLER_RTX.  */
   3856  1.1  mrg rtx
   3857  1.1  mrg tilepro_eh_return_handler_rtx (void)
   3858  1.1  mrg {
   3859  1.1  mrg   /* The MEM needs to be volatile to prevent it from being
   3860  1.1  mrg      deleted.  */
   3861  1.1  mrg   rtx tmp = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
   3862  1.1  mrg   MEM_VOLATILE_P (tmp) = true;
   3863  1.1  mrg   return tmp;
   3864  1.1  mrg }
   3865  1.1  mrg 
   3866  1.1  mrg 
   3868  1.1  mrg 
   3869  1.1  mrg /* Registers  */
   3870  1.1  mrg 
   3871  1.1  mrg /* Implemnet TARGET_CONDITIONAL_REGISTER_USAGE.  */
   3872  1.1  mrg static void
   3873  1.1  mrg tilepro_conditional_register_usage (void)
   3874  1.1  mrg {
   3875  1.1  mrg   global_regs[TILEPRO_NETORDER_REGNUM] = 1;
   3876  1.1  mrg   /* TILEPRO_PIC_TEXT_LABEL_REGNUM is conditionally used.  */
   3877  1.1  mrg   if (TILEPRO_PIC_TEXT_LABEL_REGNUM != INVALID_REGNUM)
   3878  1.1  mrg     fixed_regs[TILEPRO_PIC_TEXT_LABEL_REGNUM] = 1;
   3879  1.1  mrg   if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
   3880  1.1  mrg     fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
   3881  1.1  mrg }
   3882  1.1  mrg 
   3883  1.1  mrg 
   3884  1.1  mrg /* Implement TARGET_FRAME_POINTER_REQUIRED.  */
   3885  1.1  mrg static bool
   3886  1.1  mrg tilepro_frame_pointer_required (void)
   3887  1.1  mrg {
   3888  1.1  mrg   return crtl->calls_eh_return || cfun->calls_alloca;
   3889  1.1  mrg }
   3890  1.1  mrg 
   3891  1.1  mrg 
   3893  1.1  mrg 
   3894  1.1  mrg /* Scheduling and reorg  */
   3895  1.1  mrg 
   3896  1.1  mrg /* Return the length of INSN.  LENGTH is the initial length computed
   3897  1.1  mrg    by attributes in the machine-description file.  This is where we
   3898  1.1  mrg    account for bundles.  */
   3899  1.1  mrg int
   3900  1.1  mrg tilepro_adjust_insn_length (rtx_insn *insn, int length)
   3901  1.1  mrg {
   3902  1.1  mrg   machine_mode mode = GET_MODE (insn);
   3903  1.1  mrg 
   3904  1.1  mrg   /* A non-termininating instruction in a bundle has length 0.  */
   3905  1.1  mrg   if (mode == SImode)
   3906  1.1  mrg     return 0;
   3907  1.1  mrg 
   3908  1.1  mrg   /* By default, there is not length adjustment.  */
   3909  1.1  mrg   return length;
   3910  1.1  mrg }
   3911  1.1  mrg 
   3912  1.1  mrg 
   3913  1.1  mrg /* Implement TARGET_SCHED_ISSUE_RATE.  */
   3914  1.1  mrg static int
   3915  1.1  mrg tilepro_issue_rate (void)
   3916  1.1  mrg {
   3917  1.1  mrg   return 3;
   3918  1.1  mrg }
   3919  1.1  mrg 
   3920  1.1  mrg 
   3921  1.1  mrg /* Return the rtx for the jump target.  */
   3922  1.1  mrg static rtx
   3923  1.1  mrg get_jump_target (rtx branch)
   3924  1.1  mrg {
   3925  1.1  mrg   if (CALL_P (branch))
   3926  1.1  mrg     {
   3927  1.1  mrg       rtx call;
   3928  1.1  mrg       call = PATTERN (branch);
   3929  1.1  mrg 
   3930  1.1  mrg       if (GET_CODE (call) == PARALLEL)
   3931  1.1  mrg 	call = XVECEXP (call, 0, 0);
   3932  1.1  mrg 
   3933  1.1  mrg       if (GET_CODE (call) == SET)
   3934  1.1  mrg 	call = SET_SRC (call);
   3935  1.1  mrg 
   3936  1.1  mrg       if (GET_CODE (call) == CALL)
   3937  1.1  mrg 	return XEXP (XEXP (call, 0), 0);
   3938  1.1  mrg     }
   3939  1.1  mrg   return 0;
   3940  1.1  mrg }
   3941  1.1  mrg 
   3942  1.1  mrg /* Implement TARGET_SCHED_ADJUST_COST.  */
   3943  1.1  mrg static int
   3944  1.1  mrg tilepro_sched_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn,
   3945  1.1  mrg 			   int cost, unsigned int)
   3946  1.1  mrg {
   3947  1.1  mrg   /* If we have a true dependence, INSN is a call, and DEP_INSN
   3948  1.1  mrg      defines a register that is needed by the call (argument or stack
   3949  1.1  mrg      pointer), set its latency to 0 so that it can be bundled with
   3950  1.1  mrg      the call.  Explicitly check for and exclude the case when
   3951  1.1  mrg      DEP_INSN defines the target of the jump.  */
   3952  1.1  mrg   if (CALL_P (insn) && dep_type == REG_DEP_TRUE)
   3953  1.1  mrg     {
   3954  1.1  mrg       rtx target = get_jump_target (insn);
   3955  1.1  mrg       if (!REG_P (target) || !set_of (target, dep_insn))
   3956  1.1  mrg 	return 0;
   3957  1.1  mrg     }
   3958  1.1  mrg 
   3959  1.1  mrg   return cost;
   3960  1.1  mrg }
   3961  1.1  mrg 
   3962  1.1  mrg 
   3963  1.1  mrg /* Skip over irrelevant NOTEs and such and look for the next insn we
   3964  1.1  mrg    would consider bundling.  */
   3965  1.1  mrg static rtx_insn *
   3966  1.1  mrg next_insn_to_bundle (rtx_insn *r, rtx_insn *end)
   3967  1.1  mrg {
   3968  1.1  mrg   for (; r != end; r = NEXT_INSN (r))
   3969  1.1  mrg     {
   3970  1.1  mrg       if (NONDEBUG_INSN_P (r)
   3971  1.1  mrg 	  && GET_CODE (PATTERN (r)) != USE
   3972  1.1  mrg 	  && GET_CODE (PATTERN (r)) != CLOBBER)
   3973  1.1  mrg 	return r;
   3974  1.1  mrg     }
   3975  1.1  mrg 
   3976  1.1  mrg   return NULL;
   3977  1.1  mrg }
   3978  1.1  mrg 
   3979  1.1  mrg 
   3980  1.1  mrg /* Go through all insns, and use the information generated during
   3981  1.1  mrg    scheduling to generate SEQUENCEs to represent bundles of
   3982  1.1  mrg    instructions issued simultaneously.  */
   3983  1.1  mrg static void
   3984  1.1  mrg tilepro_gen_bundles (void)
   3985  1.1  mrg {
   3986  1.1  mrg   basic_block bb;
   3987  1.1  mrg   FOR_EACH_BB_FN (bb, cfun)
   3988  1.1  mrg   {
   3989  1.1  mrg     rtx_insn *insn, *next;
   3990  1.1  mrg     rtx_insn *end = NEXT_INSN (BB_END (bb));
   3991  1.1  mrg 
   3992  1.1  mrg     for (insn = next_insn_to_bundle (BB_HEAD (bb), end); insn; insn = next)
   3993  1.1  mrg       {
   3994  1.1  mrg 	next = next_insn_to_bundle (NEXT_INSN (insn), end);
   3995  1.1  mrg 
   3996  1.1  mrg 	/* Never wrap {} around inline asm.  */
   3997  1.1  mrg 	if (GET_CODE (PATTERN (insn)) != ASM_INPUT)
   3998  1.1  mrg 	  {
   3999  1.1  mrg 	    if (next == NULL_RTX || GET_MODE (next) == TImode
   4000  1.1  mrg 		/* NOTE: The scheduler incorrectly believes a call
   4001  1.1  mrg 		   insn can execute in the same cycle as the insn
   4002  1.1  mrg 		   after the call.  This is of course impossible.
   4003  1.1  mrg 		   Really we need to fix the scheduler somehow, so
   4004  1.1  mrg 		   the code after the call gets scheduled
   4005  1.1  mrg 		   optimally.  */
   4006  1.1  mrg 		|| CALL_P (insn))
   4007  1.1  mrg 	      {
   4008  1.1  mrg 		/* Mark current insn as the end of a bundle.  */
   4009  1.1  mrg 		PUT_MODE (insn, QImode);
   4010  1.1  mrg 	      }
   4011  1.1  mrg 	    else
   4012  1.1  mrg 	      {
   4013  1.1  mrg 		/* Mark it as part of a bundle.  */
   4014  1.1  mrg 		PUT_MODE (insn, SImode);
   4015  1.1  mrg 	      }
   4016  1.1  mrg 	  }
   4017  1.1  mrg       }
   4018  1.1  mrg   }
   4019  1.1  mrg }
   4020  1.1  mrg 
   4021  1.1  mrg 
   4022  1.1  mrg /* Helper function for tilepro_fixup_pcrel_references.  */
   4023  1.1  mrg static void
   4024  1.1  mrg replace_pc_relative_symbol_ref (rtx_insn *insn, rtx opnds[4], bool first_insn_p)
   4025  1.1  mrg {
   4026  1.1  mrg   rtx_insn *new_insns;
   4027  1.1  mrg 
   4028  1.1  mrg   start_sequence ();
   4029  1.1  mrg 
   4030  1.1  mrg   if (flag_pic == 1)
   4031  1.1  mrg     {
   4032  1.1  mrg       if (!first_insn_p)
   4033  1.1  mrg 	{
   4034  1.1  mrg 	  emit_insn (gen_add_got16 (opnds[0], tilepro_got_rtx (),
   4035  1.1  mrg 				    opnds[2]));
   4036  1.1  mrg 	  emit_insn (gen_insn_lw (opnds[0], opnds[0]));
   4037  1.1  mrg 	}
   4038  1.1  mrg     }
   4039  1.1  mrg   else
   4040  1.1  mrg     {
   4041  1.1  mrg       if (first_insn_p)
   4042  1.1  mrg 	{
   4043  1.1  mrg 	  emit_insn (gen_addhi_got32 (opnds[0], tilepro_got_rtx (),
   4044  1.1  mrg 				      opnds[2]));
   4045  1.1  mrg 	}
   4046  1.1  mrg       else
   4047  1.1  mrg 	{
   4048  1.1  mrg 	  emit_insn (gen_addlo_got32 (opnds[0], opnds[1], opnds[2]));
   4049  1.1  mrg 	  emit_insn (gen_insn_lw (opnds[0], opnds[0]));
   4050  1.1  mrg 	}
   4051  1.1  mrg     }
   4052  1.1  mrg 
   4053  1.1  mrg   new_insns = get_insns ();
   4054  1.1  mrg   end_sequence ();
   4055  1.1  mrg 
   4056  1.1  mrg   if (new_insns)
   4057  1.1  mrg     emit_insn_before (new_insns, insn);
   4058  1.1  mrg 
   4059  1.1  mrg   delete_insn (insn);
   4060  1.1  mrg }
   4061  1.1  mrg 
   4062  1.1  mrg 
   4063  1.1  mrg /* Returns whether INSN is a pc-relative addli insn.   */
   4064  1.1  mrg static bool
   4065  1.1  mrg match_addli_pcrel (rtx_insn *insn)
   4066  1.1  mrg {
   4067  1.1  mrg   rtx pattern = PATTERN (insn);
   4068  1.1  mrg   rtx unspec;
   4069  1.1  mrg 
   4070  1.1  mrg   if (GET_CODE (pattern) != SET)
   4071  1.1  mrg     return false;
   4072  1.1  mrg 
   4073  1.1  mrg   if (GET_CODE (SET_SRC (pattern)) != LO_SUM)
   4074  1.1  mrg     return false;
   4075  1.1  mrg 
   4076  1.1  mrg   if (GET_CODE (XEXP (SET_SRC (pattern), 1)) != CONST)
   4077  1.1  mrg     return false;
   4078  1.1  mrg 
   4079  1.1  mrg   unspec = XEXP (XEXP (SET_SRC (pattern), 1), 0);
   4080  1.1  mrg 
   4081  1.1  mrg   return (GET_CODE (unspec) == UNSPEC
   4082  1.1  mrg 	  && XINT (unspec, 1) == UNSPEC_PCREL_SYM);
   4083  1.1  mrg }
   4084  1.1  mrg 
   4085  1.1  mrg 
   4086  1.1  mrg /* Helper function for tilepro_fixup_pcrel_references.  */
   4087  1.1  mrg static void
   4088  1.1  mrg replace_addli_pcrel (rtx_insn *insn)
   4089  1.1  mrg {
   4090  1.1  mrg   rtx pattern = PATTERN (insn);
   4091  1.1  mrg   rtx set_src;
   4092  1.1  mrg   rtx unspec;
   4093  1.1  mrg   rtx opnds[4];
   4094  1.1  mrg   bool first_insn_p;
   4095  1.1  mrg 
   4096  1.1  mrg   gcc_assert (GET_CODE (pattern) == SET);
   4097  1.1  mrg   opnds[0] = SET_DEST (pattern);
   4098  1.1  mrg 
   4099  1.1  mrg   set_src = SET_SRC (pattern);
   4100  1.1  mrg   gcc_assert (GET_CODE (set_src) == LO_SUM);
   4101  1.1  mrg   gcc_assert (GET_CODE (XEXP (set_src, 1)) == CONST);
   4102  1.1  mrg   opnds[1] = XEXP (set_src, 0);
   4103  1.1  mrg 
   4104  1.1  mrg   unspec = XEXP (XEXP (set_src, 1), 0);
   4105  1.1  mrg   gcc_assert (GET_CODE (unspec) == UNSPEC);
   4106  1.1  mrg   gcc_assert (XINT (unspec, 1) == UNSPEC_PCREL_SYM);
   4107  1.1  mrg   opnds[2] = XVECEXP (unspec, 0, 0);
   4108  1.1  mrg   opnds[3] = XVECEXP (unspec, 0, 1);
   4109  1.1  mrg 
   4110  1.1  mrg   /* We only need to replace SYMBOL_REFs, not LABEL_REFs.  */
   4111  1.1  mrg   if (GET_CODE (opnds[2]) != SYMBOL_REF)
   4112  1.1  mrg     return;
   4113  1.1  mrg 
   4114  1.1  mrg   first_insn_p = (opnds[1] == tilepro_text_label_rtx ());
   4115  1.1  mrg 
   4116  1.1  mrg   replace_pc_relative_symbol_ref (insn, opnds, first_insn_p);
   4117  1.1  mrg }
   4118  1.1  mrg 
   4119  1.1  mrg 
   4120  1.1  mrg /* Returns whether INSN is a pc-relative auli insn.   */
   4121  1.1  mrg static bool
   4122  1.1  mrg match_auli_pcrel (rtx_insn *insn)
   4123  1.1  mrg {
   4124  1.1  mrg   rtx pattern = PATTERN (insn);
   4125  1.1  mrg   rtx high;
   4126  1.1  mrg   rtx unspec;
   4127  1.1  mrg 
   4128  1.1  mrg   if (GET_CODE (pattern) != SET)
   4129  1.1  mrg     return false;
   4130  1.1  mrg 
   4131  1.1  mrg   if (GET_CODE (SET_SRC (pattern)) != PLUS)
   4132  1.1  mrg     return false;
   4133  1.1  mrg 
   4134  1.1  mrg   high = XEXP (SET_SRC (pattern), 1);
   4135  1.1  mrg 
   4136  1.1  mrg   if (GET_CODE (high) != HIGH
   4137  1.1  mrg       || GET_CODE (XEXP (high, 0)) != CONST)
   4138  1.1  mrg     return false;
   4139  1.1  mrg 
   4140  1.1  mrg   unspec = XEXP (XEXP (high, 0), 0);
   4141  1.1  mrg 
   4142  1.1  mrg   return (GET_CODE (unspec) == UNSPEC
   4143  1.1  mrg 	  && XINT (unspec, 1) == UNSPEC_PCREL_SYM);
   4144  1.1  mrg }
   4145  1.1  mrg 
   4146  1.1  mrg 
   4147  1.1  mrg /* Helper function for tilepro_fixup_pcrel_references.  */
   4148  1.1  mrg static void
   4149  1.1  mrg replace_auli_pcrel (rtx_insn *insn)
   4150  1.1  mrg {
   4151  1.1  mrg   rtx pattern = PATTERN (insn);
   4152  1.1  mrg   rtx set_src;
   4153  1.1  mrg   rtx high;
   4154  1.1  mrg   rtx unspec;
   4155  1.1  mrg   rtx opnds[4];
   4156  1.1  mrg   bool first_insn_p;
   4157  1.1  mrg 
   4158  1.1  mrg   gcc_assert (GET_CODE (pattern) == SET);
   4159  1.1  mrg   opnds[0] = SET_DEST (pattern);
   4160  1.1  mrg 
   4161  1.1  mrg   set_src = SET_SRC (pattern);
   4162  1.1  mrg   gcc_assert (GET_CODE (set_src) == PLUS);
   4163  1.1  mrg   opnds[1] = XEXP (set_src, 0);
   4164  1.1  mrg 
   4165  1.1  mrg   high = XEXP (set_src, 1);
   4166  1.1  mrg   gcc_assert (GET_CODE (high) == HIGH);
   4167  1.1  mrg   gcc_assert (GET_CODE (XEXP (high, 0)) == CONST);
   4168  1.1  mrg 
   4169  1.1  mrg   unspec = XEXP (XEXP (high, 0), 0);
   4170  1.1  mrg   gcc_assert (GET_CODE (unspec) == UNSPEC);
   4171  1.1  mrg   gcc_assert (XINT (unspec, 1) == UNSPEC_PCREL_SYM);
   4172  1.1  mrg   opnds[2] = XVECEXP (unspec, 0, 0);
   4173  1.1  mrg   opnds[3] = XVECEXP (unspec, 0, 1);
   4174  1.1  mrg 
   4175  1.1  mrg   /* We only need to replace SYMBOL_REFs, not LABEL_REFs.  */
   4176  1.1  mrg   if (GET_CODE (opnds[2]) != SYMBOL_REF)
   4177  1.1  mrg     return;
   4178  1.1  mrg 
   4179  1.1  mrg   first_insn_p = (opnds[1] == tilepro_text_label_rtx ());
   4180  1.1  mrg 
   4181  1.1  mrg   replace_pc_relative_symbol_ref (insn, opnds, first_insn_p);
   4182  1.1  mrg }
   4183  1.1  mrg 
   4184  1.1  mrg 
   4185  1.1  mrg /* We generate PC relative SYMBOL_REFs as an optimization, to avoid
   4186  1.1  mrg    going through the GOT when the symbol is local to the compilation
   4187  1.1  mrg    unit.  But such a symbol requires that the common text_label that
   4188  1.1  mrg    we generate at the beginning of the function be in the same section
   4189  1.1  mrg    as the reference to the SYMBOL_REF.  This may not be true if we
   4190  1.1  mrg    generate hot/cold sections.  This function looks for such cases and
   4191  1.1  mrg    replaces such references with the longer sequence going through the
   4192  1.1  mrg    GOT.
   4193  1.1  mrg 
   4194  1.1  mrg    We expect one of the following two instruction sequences:
   4195  1.1  mrg    addli tmp1, txt_label_reg, lo16(sym - txt_label)
   4196  1.1  mrg    auli  tmp2,          tmp1, ha16(sym - txt_label)
   4197  1.1  mrg 
   4198  1.1  mrg    auli  tmp1, txt_label_reg, ha16(sym - txt_label)
   4199  1.1  mrg    addli tmp2,          tmp1, lo16(sym - txt_label)
   4200  1.1  mrg 
   4201  1.1  mrg    If we're compiling -fpic, we replace the first instruction with
   4202  1.1  mrg    nothing, and the second instruction with:
   4203  1.1  mrg 
   4204  1.1  mrg    addli tmp2, got_rtx, got(sym)
   4205  1.1  mrg    lw    tmp2,    tmp2
   4206  1.1  mrg 
   4207  1.1  mrg    If we're compiling -fPIC, we replace the first instruction with:
   4208  1.1  mrg 
   4209  1.1  mrg    auli  tmp1, got_rtx, got_ha16(sym)
   4210  1.1  mrg 
   4211  1.1  mrg    and the second instruction with:
   4212  1.1  mrg 
   4213  1.1  mrg    addli tmp2,    tmp1, got_lo16(sym)
   4214  1.1  mrg    lw    tmp2,    tmp2
   4215  1.1  mrg 
   4216  1.1  mrg    Note that we're careful to disturb the instruction sequence as
   4217  1.1  mrg    little as possible, since it's very late in the compilation
   4218  1.1  mrg    process.
   4219  1.1  mrg */
   4220  1.1  mrg static void
   4221  1.1  mrg tilepro_fixup_pcrel_references (void)
   4222  1.1  mrg {
   4223  1.1  mrg   rtx_insn *insn, *next_insn;
   4224  1.1  mrg   bool same_section_as_entry = true;
   4225  1.1  mrg 
   4226  1.1  mrg   for (insn = get_insns (); insn; insn = next_insn)
   4227  1.1  mrg     {
   4228  1.1  mrg       next_insn = NEXT_INSN (insn);
   4229  1.1  mrg 
   4230  1.1  mrg       if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
   4231  1.1  mrg 	{
   4232  1.1  mrg 	  same_section_as_entry = !same_section_as_entry;
   4233  1.1  mrg 	  continue;
   4234  1.1  mrg 	}
   4235  1.1  mrg 
   4236  1.1  mrg       if (same_section_as_entry)
   4237  1.1  mrg       	continue;
   4238  1.1  mrg 
   4239  1.1  mrg       if (!(INSN_P (insn)
   4240  1.1  mrg 	    && GET_CODE (PATTERN (insn)) != USE
   4241  1.1  mrg 	    && GET_CODE (PATTERN (insn)) != CLOBBER))
   4242  1.1  mrg 	continue;
   4243  1.1  mrg 
   4244  1.1  mrg       if (match_addli_pcrel (insn))
   4245  1.1  mrg 	replace_addli_pcrel (insn);
   4246  1.1  mrg       else if (match_auli_pcrel (insn))
   4247  1.1  mrg 	replace_auli_pcrel (insn);
   4248  1.1  mrg     }
   4249  1.1  mrg }
   4250  1.1  mrg 
   4251  1.1  mrg 
   4252  1.1  mrg /* Ensure that no var tracking notes are emitted in the middle of a
   4253  1.1  mrg    three-instruction bundle.  */
   4254  1.1  mrg static void
   4255  1.1  mrg reorder_var_tracking_notes (void)
   4256  1.1  mrg {
   4257  1.1  mrg   basic_block bb;
   4258  1.1  mrg   FOR_EACH_BB_FN (bb, cfun)
   4259  1.1  mrg   {
   4260  1.1  mrg     rtx_insn *insn, *next;
   4261  1.1  mrg     rtx_insn *queue = NULL;
   4262  1.1  mrg     bool in_bundle = false;
   4263  1.1  mrg 
   4264  1.1  mrg     for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = next)
   4265  1.1  mrg       {
   4266  1.1  mrg 	next = NEXT_INSN (insn);
   4267  1.1  mrg 
   4268  1.1  mrg 	if (INSN_P (insn))
   4269  1.1  mrg 	  {
   4270  1.1  mrg 	    /* Emit queued up notes at the last instruction of a bundle.  */
   4271  1.1  mrg 	    if (GET_MODE (insn) == QImode)
   4272  1.1  mrg 	      {
   4273  1.1  mrg 		while (queue)
   4274  1.1  mrg 		  {
   4275  1.1  mrg 		    rtx_insn *next_queue = PREV_INSN (queue);
   4276  1.1  mrg 		    SET_PREV_INSN (NEXT_INSN (insn)) = queue;
   4277  1.1  mrg 		    SET_NEXT_INSN (queue) = NEXT_INSN (insn);
   4278  1.1  mrg 		    SET_NEXT_INSN (insn) = queue;
   4279  1.1  mrg 		    SET_PREV_INSN (queue) = insn;
   4280  1.1  mrg 		    queue = next_queue;
   4281  1.1  mrg 		  }
   4282  1.1  mrg 		in_bundle = false;
   4283  1.1  mrg 	      }
   4284  1.1  mrg 	    else if (GET_MODE (insn) == SImode)
   4285  1.1  mrg 	      in_bundle = true;
   4286  1.1  mrg 	  }
   4287  1.1  mrg 	else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
   4288  1.1  mrg 	  {
   4289  1.1  mrg 	    if (in_bundle)
   4290  1.1  mrg 	      {
   4291  1.1  mrg 		rtx_insn *prev = PREV_INSN (insn);
   4292  1.1  mrg 		SET_PREV_INSN (next) = prev;
   4293  1.1  mrg 		SET_NEXT_INSN (prev) = next;
   4294  1.1  mrg 
   4295  1.1  mrg 		SET_PREV_INSN (insn) = queue;
   4296  1.1  mrg 		queue = insn;
   4297  1.1  mrg 	      }
   4298  1.1  mrg 	  }
   4299  1.1  mrg       }
   4300  1.1  mrg   }
   4301  1.1  mrg }
   4302  1.1  mrg 
   4303  1.1  mrg 
   4304  1.1  mrg /* Perform machine dependent operations on the rtl chain INSNS.  */
   4305  1.1  mrg static void
   4306  1.1  mrg tilepro_reorg (void)
   4307  1.1  mrg {
   4308  1.1  mrg   /* We are freeing block_for_insn in the toplev to keep compatibility
   4309  1.1  mrg      with old MDEP_REORGS that are not CFG based.  Recompute it
   4310  1.1  mrg      now.  */
   4311  1.1  mrg   compute_bb_for_insn ();
   4312  1.1  mrg 
   4313  1.1  mrg   if (flag_reorder_blocks_and_partition)
   4314  1.1  mrg     {
   4315  1.1  mrg       tilepro_fixup_pcrel_references ();
   4316  1.1  mrg     }
   4317  1.1  mrg 
   4318  1.1  mrg   if (flag_schedule_insns_after_reload)
   4319  1.1  mrg     {
   4320  1.1  mrg       split_all_insns ();
   4321  1.1  mrg 
   4322  1.1  mrg       timevar_push (TV_SCHED2);
   4323  1.1  mrg       schedule_insns ();
   4324  1.1  mrg       timevar_pop (TV_SCHED2);
   4325  1.1  mrg 
   4326  1.1  mrg       /* Examine the schedule to group into bundles.  */
   4327  1.1  mrg       tilepro_gen_bundles ();
   4328  1.1  mrg     }
   4329  1.1  mrg 
   4330  1.1  mrg   df_analyze ();
   4331  1.1  mrg 
   4332  1.1  mrg   if (flag_var_tracking)
   4333  1.1  mrg     {
   4334  1.1  mrg       timevar_push (TV_VAR_TRACKING);
   4335  1.1  mrg       variable_tracking_main ();
   4336  1.1  mrg       reorder_var_tracking_notes ();
   4337  1.1  mrg       timevar_pop (TV_VAR_TRACKING);
   4338  1.1  mrg     }
   4339  1.1  mrg 
   4340  1.1  mrg   df_finish_pass (false);
   4341  1.1  mrg }
   4342  1.1  mrg 
   4343  1.1  mrg 
   4345  1.1  mrg 
   4346  1.1  mrg /* Assembly  */
   4347  1.1  mrg 
   4348  1.1  mrg /* Select a format to encode pointers in exception handling data.
   4349  1.1  mrg    CODE is 0 for data, 1 for code labels, 2 for function pointers.
   4350  1.1  mrg    GLOBAL is true if the symbol may be affected by dynamic
   4351  1.1  mrg    relocations.  */
   4352  1.1  mrg int
   4353  1.1  mrg tilepro_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED, int global)
   4354  1.1  mrg {
   4355  1.1  mrg   return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
   4356  1.1  mrg }
   4357  1.1  mrg 
   4358  1.1  mrg 
   4359  1.1  mrg /* Implement TARGET_ASM_OUTPUT_MI_THUNK.  */
   4360  1.1  mrg static void
   4361  1.1  mrg tilepro_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   4362  1.1  mrg 			     HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
   4363  1.1  mrg 			     tree function)
   4364  1.1  mrg {
   4365  1.1  mrg   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   4366  1.1  mrg   rtx this_rtx, funexp;
   4367  1.1  mrg   rtx_insn *insn;
   4368  1.1  mrg 
   4369  1.1  mrg   /* Pretend to be a post-reload pass while generating rtl.  */
   4370  1.1  mrg   reload_completed = 1;
   4371  1.1  mrg 
   4372  1.1  mrg   /* Mark the end of the (empty) prologue.  */
   4373  1.1  mrg   emit_note (NOTE_INSN_PROLOGUE_END);
   4374  1.1  mrg 
   4375  1.1  mrg   /* Find the "this" pointer.  If the function returns a structure,
   4376  1.1  mrg      the structure return pointer is in $1.  */
   4377  1.1  mrg   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
   4378  1.1  mrg     this_rtx = gen_rtx_REG (Pmode, 1);
   4379  1.1  mrg   else
   4380  1.1  mrg     this_rtx = gen_rtx_REG (Pmode, 0);
   4381  1.1  mrg 
   4382  1.1  mrg   /* Add DELTA to THIS_RTX.  */
   4383  1.1  mrg   emit_insn (gen_addsi3 (this_rtx, this_rtx, GEN_INT (delta)));
   4384  1.1  mrg 
   4385  1.1  mrg   /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX.  */
   4386  1.1  mrg   if (vcall_offset)
   4387  1.1  mrg     {
   4388  1.1  mrg       rtx tmp;
   4389  1.1  mrg 
   4390  1.1  mrg       tmp = gen_rtx_REG (Pmode, 29);
   4391  1.1  mrg       emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
   4392  1.1  mrg 
   4393  1.1  mrg       emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (vcall_offset)));
   4394  1.1  mrg 
   4395  1.1  mrg       emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
   4396  1.1  mrg 
   4397  1.1  mrg       emit_insn (gen_addsi3 (this_rtx, this_rtx, tmp));
   4398  1.1  mrg     }
   4399  1.1  mrg 
   4400  1.1  mrg   /* Generate a tail call to the target function.  */
   4401  1.1  mrg   if (!TREE_USED (function))
   4402  1.1  mrg     {
   4403  1.1  mrg       assemble_external (function);
   4404  1.1  mrg       TREE_USED (function) = 1;
   4405  1.1  mrg     }
   4406  1.1  mrg   funexp = XEXP (DECL_RTL (function), 0);
   4407  1.1  mrg   funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
   4408  1.1  mrg   insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
   4409  1.1  mrg   SIBLING_CALL_P (insn) = 1;
   4410  1.1  mrg 
   4411  1.1  mrg   /* Run just enough of rest_of_compilation to get the insns emitted.
   4412  1.1  mrg      There's not really enough bulk here to make other passes such as
   4413  1.1  mrg      instruction scheduling worth while.
   4414  1.1  mrg 
   4415  1.1  mrg      We don't currently bundle, but the instruciton sequence is all
   4416  1.1  mrg      serial except for the tail call, so we're only wasting one cycle.
   4417  1.1  mrg    */
   4418  1.1  mrg   insn = get_insns ();
   4419  1.1  mrg   shorten_branches (insn);
   4420  1.1  mrg   assemble_start_function (thunk_fndecl, fnname);
   4421  1.1  mrg   final_start_function (insn, file, 1);
   4422  1.1  mrg   final (insn, file, 1);
   4423  1.1  mrg   final_end_function ();
   4424  1.1  mrg   assemble_end_function (thunk_fndecl, fnname);
   4425  1.1  mrg 
   4426  1.1  mrg   /* Stop pretending to be a post-reload pass.  */
   4427  1.1  mrg   reload_completed = 0;
   4428  1.1  mrg }
   4429  1.1  mrg 
   4430  1.1  mrg 
   4431  1.1  mrg /* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE.  */
   4432  1.1  mrg static void
   4433  1.1  mrg tilepro_asm_trampoline_template (FILE *file)
   4434  1.1  mrg {
   4435  1.1  mrg   fprintf (file, "\tlnk   r10\n");
   4436  1.1  mrg   fprintf (file, "\taddi  r10, r10, 32\n");
   4437  1.1  mrg   fprintf (file, "\tlwadd r11, r10, %d\n", GET_MODE_SIZE (ptr_mode));
   4438  1.1  mrg   fprintf (file, "\tlw    r10, r10\n");
   4439  1.1  mrg   fprintf (file, "\tjr    r11\n");
   4440  1.1  mrg   fprintf (file, "\t.word 0 # <function address>\n");
   4441  1.1  mrg   fprintf (file, "\t.word 0 # <static chain value>\n");
   4442  1.1  mrg }
   4443  1.1  mrg 
   4444  1.1  mrg 
   4445  1.1  mrg /* Implement TARGET_TRAMPOLINE_INIT.  */
   4446  1.1  mrg static void
   4447  1.1  mrg tilepro_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
   4448  1.1  mrg {
   4449  1.1  mrg   rtx fnaddr, chaddr;
   4450  1.1  mrg   rtx mem;
   4451  1.1  mrg   rtx begin_addr, end_addr;
   4452  1.1  mrg   int ptr_mode_size = GET_MODE_SIZE (ptr_mode);
   4453  1.1  mrg 
   4454  1.1  mrg   fnaddr = copy_to_reg (XEXP (DECL_RTL (fndecl), 0));
   4455  1.1  mrg   chaddr = copy_to_reg (static_chain);
   4456  1.1  mrg 
   4457  1.1  mrg   emit_block_move (m_tramp, assemble_trampoline_template (),
   4458  1.1  mrg 		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
   4459  1.1  mrg 
   4460  1.1  mrg   mem = adjust_address (m_tramp, ptr_mode,
   4461  1.1  mrg 			TRAMPOLINE_SIZE - 2 * ptr_mode_size);
   4462  1.1  mrg   emit_move_insn (mem, fnaddr);
   4463  1.1  mrg   mem = adjust_address (m_tramp, ptr_mode,
   4464  1.1  mrg 			TRAMPOLINE_SIZE - ptr_mode_size);
   4465  1.1  mrg   emit_move_insn (mem, chaddr);
   4466  1.1  mrg 
   4467  1.1  mrg   /* Get pointers to the beginning and end of the code block.  */
   4468  1.1  mrg   begin_addr = force_reg (Pmode, XEXP (m_tramp, 0));
   4469  1.1  mrg   end_addr = force_reg (Pmode, plus_constant (Pmode, XEXP (m_tramp, 0),
   4470  1.1  mrg 					      TRAMPOLINE_SIZE));
   4471  1.1  mrg 
   4472  1.1  mrg   maybe_emit_call_builtin___clear_cache (begin_addr, end_addr);
   4473  1.1  mrg }
   4474  1.1  mrg 
   4475  1.1  mrg 
   4476  1.1  mrg /* Implement TARGET_PRINT_OPERAND.  */
   4477  1.1  mrg static void
   4478  1.1  mrg tilepro_print_operand (FILE *file, rtx x, int code)
   4479  1.1  mrg {
   4480  1.1  mrg   switch (code)
   4481  1.1  mrg     {
   4482  1.1  mrg     case 'c':
   4483  1.1  mrg       /* Print the compare operator opcode for conditional moves. */
   4484  1.1  mrg       switch (GET_CODE (x))
   4485  1.1  mrg 	{
   4486  1.1  mrg 	case EQ:
   4487  1.1  mrg 	  fputs ("z", file);
   4488  1.1  mrg 	  break;
   4489  1.1  mrg 	case NE:
   4490  1.1  mrg 	  fputs ("nz", file);
   4491  1.1  mrg 	  break;
   4492  1.1  mrg 	default:
   4493  1.1  mrg 	  output_operand_lossage ("invalid %%c operand");
   4494  1.1  mrg 	}
   4495  1.1  mrg       return;
   4496  1.1  mrg 
   4497  1.1  mrg     case 'C':
   4498  1.1  mrg       /* Print the compare operator opcode for conditional moves. */
   4499  1.1  mrg       switch (GET_CODE (x))
   4500  1.1  mrg 	{
   4501  1.1  mrg 	case EQ:
   4502  1.1  mrg 	  fputs ("nz", file);
   4503  1.1  mrg 	  break;
   4504  1.1  mrg 	case NE:
   4505  1.1  mrg 	  fputs ("z", file);
   4506  1.1  mrg 	  break;
   4507  1.1  mrg 	default:
   4508  1.1  mrg 	  output_operand_lossage ("invalid %%C operand");
   4509  1.1  mrg 	}
   4510  1.1  mrg       return;
   4511  1.1  mrg 
   4512  1.1  mrg     case 'h':
   4513  1.1  mrg       {
   4514  1.1  mrg 	/* Print the high 16 bits of a 32-bit constant.  */
   4515  1.1  mrg 	HOST_WIDE_INT i;
   4516  1.1  mrg 	if (CONST_INT_P (x))
   4517  1.1  mrg 	  i = INTVAL (x);
   4518  1.1  mrg 	else if (GET_CODE (x) == CONST_DOUBLE)
   4519  1.1  mrg 	  i = CONST_DOUBLE_LOW (x);
   4520  1.1  mrg 	else
   4521  1.1  mrg 	  {
   4522  1.1  mrg 	    output_operand_lossage ("invalid %%h operand");
   4523  1.1  mrg 	    return;
   4524  1.1  mrg 	  }
   4525  1.1  mrg 	i = trunc_int_for_mode (i >> 16, HImode);
   4526  1.1  mrg 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, i);
   4527  1.1  mrg 	return;
   4528  1.1  mrg       }
   4529  1.1  mrg 
   4530  1.1  mrg     case 'H':
   4531  1.1  mrg       {
   4532  1.1  mrg 	rtx addr = NULL;
   4533  1.1  mrg 	const char *opstr = NULL;
   4534  1.1  mrg 	bool pcrel = false;
   4535  1.1  mrg 	if (GET_CODE (x) == CONST
   4536  1.1  mrg 	    && GET_CODE (XEXP (x, 0)) == UNSPEC)
   4537  1.1  mrg 	  {
   4538  1.1  mrg 	    addr = XVECEXP (XEXP (x, 0), 0, 0);
   4539  1.1  mrg 	    switch (XINT (XEXP (x, 0), 1))
   4540  1.1  mrg 	    {
   4541  1.1  mrg 	    case UNSPEC_GOT32_SYM:
   4542  1.1  mrg 	      opstr = "got_ha16";
   4543  1.1  mrg 	      break;
   4544  1.1  mrg 	    case UNSPEC_PCREL_SYM:
   4545  1.1  mrg 	      opstr = "ha16";
   4546  1.1  mrg 	      pcrel = true;
   4547  1.1  mrg 	      break;
   4548  1.1  mrg 	    case UNSPEC_TLS_GD:
   4549  1.1  mrg 	      opstr = "tls_gd_ha16";
   4550  1.1  mrg 	      break;
   4551  1.1  mrg 	    case UNSPEC_TLS_IE:
   4552  1.1  mrg 	      opstr = "tls_ie_ha16";
   4553  1.1  mrg 	      break;
   4554  1.1  mrg 	    case UNSPEC_TLS_LE:
   4555  1.1  mrg 	      opstr = "tls_le_ha16";
   4556  1.1  mrg 	      break;
   4557  1.1  mrg 	    default:
   4558  1.1  mrg 	      output_operand_lossage ("invalid %%H operand");
   4559  1.1  mrg 	    }
   4560  1.1  mrg 	  }
   4561  1.1  mrg 	else
   4562  1.1  mrg 	  {
   4563  1.1  mrg 	    addr = x;
   4564  1.1  mrg 	    opstr = "ha16";
   4565  1.1  mrg 	  }
   4566  1.1  mrg 
   4567  1.1  mrg 	fputs (opstr, file);
   4568  1.1  mrg 	fputc ('(', file);
   4569  1.1  mrg 	output_addr_const (file, addr);
   4570  1.1  mrg 
   4571  1.1  mrg 	if (pcrel)
   4572  1.1  mrg 	  {
   4573  1.1  mrg 	    rtx addr2 = XVECEXP (XEXP (x, 0), 0, 1);
   4574  1.1  mrg 	    fputs (" - " , file);
   4575  1.1  mrg 	    output_addr_const (file, addr2);
   4576  1.1  mrg 	  }
   4577  1.1  mrg 
   4578  1.1  mrg 	fputc (')', file);
   4579  1.1  mrg 	return;
   4580  1.1  mrg       }
   4581  1.1  mrg 
   4582  1.1  mrg     case 'I':
   4583  1.1  mrg       /* Print an auto-inc memory operand.  */
   4584  1.1  mrg       if (!MEM_P (x))
   4585  1.1  mrg 	{
   4586  1.1  mrg 	  output_operand_lossage ("invalid %%I operand");
   4587  1.1  mrg 	  return;
   4588  1.1  mrg 	}
   4589  1.1  mrg 
   4590  1.1  mrg       output_memory_autoinc_first = true;
   4591  1.1  mrg       output_address (GET_MODE (x), XEXP (x, 0));
   4592  1.1  mrg       return;
   4593  1.1  mrg 
   4594  1.1  mrg     case 'i':
   4595  1.1  mrg       /* Print an auto-inc memory operand.  */
   4596  1.1  mrg       if (!MEM_P (x))
   4597  1.1  mrg 	{
   4598  1.1  mrg 	  output_operand_lossage ("invalid %%i operand");
   4599  1.1  mrg 	  return;
   4600  1.1  mrg 	}
   4601  1.1  mrg 
   4602  1.1  mrg       output_memory_autoinc_first = false;
   4603  1.1  mrg       output_address (GET_MODE (x), XEXP (x, 0));
   4604  1.1  mrg       return;
   4605  1.1  mrg 
   4606  1.1  mrg     case 'j':
   4607  1.1  mrg       {
   4608  1.1  mrg 	/* Print the low 8 bits of a constant.  */
   4609  1.1  mrg 	HOST_WIDE_INT i;
   4610  1.1  mrg 	if (CONST_INT_P (x))
   4611  1.1  mrg 	  i = INTVAL (x);
   4612  1.1  mrg 	else if (GET_CODE (x) == CONST_DOUBLE)
   4613  1.1  mrg 	  i = CONST_DOUBLE_LOW (x);
   4614  1.1  mrg 	else if (GET_CODE (x) == CONST_VECTOR
   4615  1.1  mrg 		 && CONST_INT_P (CONST_VECTOR_ELT (x, 0)))
   4616  1.1  mrg 	  i = INTVAL (CONST_VECTOR_ELT (x, 0));
   4617  1.1  mrg 	else
   4618  1.1  mrg 	  {
   4619  1.1  mrg 	    output_operand_lossage ("invalid %%j operand");
   4620  1.1  mrg 	    return;
   4621  1.1  mrg 	  }
   4622  1.1  mrg 	i = trunc_int_for_mode (i, QImode);
   4623  1.1  mrg 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, i);
   4624  1.1  mrg 	return;
   4625  1.1  mrg       }
   4626  1.1  mrg 
   4627  1.1  mrg     case 'L':
   4628  1.1  mrg       {
   4629  1.1  mrg 	rtx addr = NULL;
   4630  1.1  mrg 	const char *opstr = NULL;
   4631  1.1  mrg 	bool pcrel = false;
   4632  1.1  mrg 	if (GET_CODE (x) == CONST
   4633  1.1  mrg 	    && GET_CODE (XEXP (x, 0)) == UNSPEC)
   4634  1.1  mrg 	  {
   4635  1.1  mrg 	    addr = XVECEXP (XEXP (x, 0), 0, 0);
   4636  1.1  mrg 	    switch (XINT (XEXP (x, 0), 1))
   4637  1.1  mrg 	    {
   4638  1.1  mrg 	    case UNSPEC_GOT16_SYM:
   4639  1.1  mrg 	      opstr = "got";
   4640  1.1  mrg 	      break;
   4641  1.1  mrg 	    case UNSPEC_GOT32_SYM:
   4642  1.1  mrg 	      opstr = "got_lo16";
   4643  1.1  mrg 	      break;
   4644  1.1  mrg 	    case UNSPEC_PCREL_SYM:
   4645  1.1  mrg 	      opstr = "lo16";
   4646  1.1  mrg 	      pcrel = true;
   4647  1.1  mrg 	      break;
   4648  1.1  mrg 	    case UNSPEC_TLS_GD:
   4649  1.1  mrg 	      opstr = "tls_gd_lo16";
   4650  1.1  mrg 	      break;
   4651  1.1  mrg 	    case UNSPEC_TLS_IE:
   4652  1.1  mrg 	      opstr = "tls_ie_lo16";
   4653  1.1  mrg 	      break;
   4654  1.1  mrg 	    case UNSPEC_TLS_LE:
   4655  1.1  mrg 	      opstr = "tls_le_lo16";
   4656  1.1  mrg 	      break;
   4657  1.1  mrg 	    default:
   4658  1.1  mrg 	      output_operand_lossage ("invalid %%L operand");
   4659  1.1  mrg 	    }
   4660  1.1  mrg 	  }
   4661  1.1  mrg 	else
   4662  1.1  mrg 	  {
   4663  1.1  mrg 	    addr = x;
   4664  1.1  mrg 	    opstr = "lo16";
   4665  1.1  mrg 	  }
   4666  1.1  mrg 
   4667  1.1  mrg 	fputs (opstr, file);
   4668  1.1  mrg 	fputc ('(', file);
   4669  1.1  mrg 	output_addr_const (file, addr);
   4670  1.1  mrg 
   4671  1.1  mrg 	if (pcrel)
   4672  1.1  mrg 	  {
   4673  1.1  mrg 	    rtx addr2 = XVECEXP (XEXP (x, 0), 0, 1);
   4674  1.1  mrg 	    fputs (" - " , file);
   4675  1.1  mrg 	    output_addr_const (file, addr2);
   4676  1.1  mrg 	  }
   4677  1.1  mrg 
   4678  1.1  mrg 	fputc (')', file);
   4679  1.1  mrg 	return;
   4680  1.1  mrg       }
   4681  1.1  mrg 
   4682  1.1  mrg     case 'p':
   4683  1.1  mrg       if (GET_CODE (x) == SYMBOL_REF)
   4684  1.1  mrg 	{
   4685  1.1  mrg 	  if (flag_pic && !SYMBOL_REF_LOCAL_P (x))
   4686  1.1  mrg 	    fprintf (file, "plt(");
   4687  1.1  mrg 	  output_addr_const (file, x);
   4688  1.1  mrg 	  if (flag_pic && !SYMBOL_REF_LOCAL_P (x))
   4689  1.1  mrg 	    fprintf (file, ")");
   4690  1.1  mrg 	}
   4691  1.1  mrg       else
   4692  1.1  mrg 	output_addr_const (file, x);
   4693  1.1  mrg       return;
   4694  1.1  mrg 
   4695  1.1  mrg     case 'P':
   4696  1.1  mrg       {
   4697  1.1  mrg 	/* Print a 32-bit constant plus one.  */
   4698  1.1  mrg 	HOST_WIDE_INT i;
   4699  1.1  mrg 	if (!CONST_INT_P (x))
   4700  1.1  mrg 	  {
   4701  1.1  mrg 	    output_operand_lossage ("invalid %%P operand");
   4702  1.1  mrg 	    return;
   4703  1.1  mrg 	  }
   4704  1.1  mrg 	i = trunc_int_for_mode (INTVAL (x) + 1, SImode);
   4705  1.1  mrg 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, i);
   4706  1.1  mrg 	return;
   4707  1.1  mrg       }
   4708  1.1  mrg 
   4709  1.1  mrg     case 'M':
   4710  1.1  mrg       {
   4711  1.1  mrg 	/* Print an mm-style bit range.  */
   4712  1.1  mrg 	int first_bit, last_bit;
   4713  1.1  mrg 
   4714  1.1  mrg 	if (!CONST_INT_P (x)
   4715  1.1  mrg 	    || !tilepro_bitfield_operand_p (INTVAL (x), &first_bit,
   4716  1.1  mrg 					    &last_bit))
   4717  1.1  mrg 	  {
   4718  1.1  mrg 	    output_operand_lossage ("invalid %%M operand");
   4719  1.1  mrg 	    return;
   4720  1.1  mrg 	  }
   4721  1.1  mrg 
   4722  1.1  mrg 	fprintf (file, "%d, %d", first_bit, last_bit);
   4723  1.1  mrg 	return;
   4724  1.1  mrg       }
   4725  1.1  mrg 
   4726  1.1  mrg     case 'N':
   4727  1.1  mrg       {
   4728  1.1  mrg 	const char *reg = NULL;
   4729  1.1  mrg 
   4730  1.1  mrg 	/* Print a network register.  */
   4731  1.1  mrg 	if (!CONST_INT_P (x))
   4732  1.1  mrg 	  {
   4733  1.1  mrg 	    output_operand_lossage ("invalid %%N operand");
   4734  1.1  mrg 	    return;
   4735  1.1  mrg 	  }
   4736  1.1  mrg 
   4737  1.1  mrg 	switch (INTVAL (x))
   4738  1.1  mrg 	  {
   4739  1.1  mrg 	  case TILEPRO_NETREG_IDN0: reg = "idn0"; break;
   4740  1.1  mrg 	  case TILEPRO_NETREG_IDN1: reg = "idn1"; break;
   4741  1.1  mrg 	  case TILEPRO_NETREG_SN:   reg = "sn";   break;
   4742  1.1  mrg 	  case TILEPRO_NETREG_UDN0: reg = "udn0"; break;
   4743  1.1  mrg 	  case TILEPRO_NETREG_UDN1: reg = "udn1"; break;
   4744  1.1  mrg 	  case TILEPRO_NETREG_UDN2: reg = "udn2"; break;
   4745  1.1  mrg 	  case TILEPRO_NETREG_UDN3: reg = "udn3"; break;
   4746  1.1  mrg 	  default: gcc_unreachable ();
   4747  1.1  mrg 	  }
   4748  1.1  mrg 
   4749  1.1  mrg 	fprintf (file, reg);
   4750  1.1  mrg 	return;
   4751  1.1  mrg       }
   4752  1.1  mrg 
   4753  1.1  mrg     case 't':
   4754  1.1  mrg       {
   4755  1.1  mrg 	/* Log base 2 of a power of two.  */
   4756  1.1  mrg 	HOST_WIDE_INT i;
   4757  1.1  mrg 	HOST_WIDE_INT n;
   4758  1.1  mrg 
   4759  1.1  mrg 	if (!CONST_INT_P (x))
   4760  1.1  mrg 	  {
   4761  1.1  mrg 	    output_operand_lossage ("invalid %%t operand");
   4762  1.1  mrg 	    return;
   4763  1.1  mrg 	  }
   4764  1.1  mrg 	n = trunc_int_for_mode (INTVAL (x), SImode);
   4765  1.1  mrg 	i = exact_log2 (n);
   4766  1.1  mrg 	if (i < 0)
   4767  1.1  mrg 	  {
   4768  1.1  mrg 	    output_operand_lossage ("invalid %%t operand");
   4769  1.1  mrg 	    return;
   4770  1.1  mrg 	  }
   4771  1.1  mrg 
   4772  1.1  mrg 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, i);
   4773  1.1  mrg 	return;
   4774  1.1  mrg       }
   4775  1.1  mrg       break;
   4776  1.1  mrg 
   4777  1.1  mrg     case 'r':
   4778  1.1  mrg       /* In this case we need a register.  Use 'zero' if the
   4779  1.1  mrg          operand is const0_rtx.  */
   4780  1.1  mrg       if (x == const0_rtx
   4781  1.1  mrg 	  || (GET_MODE (x) != VOIDmode && x == CONST0_RTX (GET_MODE (x))))
   4782  1.1  mrg 	{
   4783  1.1  mrg 	  fputs ("zero", file);
   4784  1.1  mrg 	  return;
   4785  1.1  mrg 	}
   4786  1.1  mrg       else if (!REG_P (x))
   4787  1.1  mrg 	{
   4788  1.1  mrg 	  output_operand_lossage ("invalid %%r operand");
   4789  1.1  mrg 	  return;
   4790  1.1  mrg 	}
   4791  1.1  mrg       /* FALLTHRU */
   4792  1.1  mrg 
   4793  1.1  mrg     case 0:
   4794  1.1  mrg       if (REG_P (x))
   4795  1.1  mrg 	{
   4796  1.1  mrg 	  fprintf (file, "%s", reg_names[REGNO (x)]);
   4797  1.1  mrg 	  return;
   4798  1.1  mrg 	}
   4799  1.1  mrg       else if (MEM_P (x))
   4800  1.1  mrg 	{
   4801  1.1  mrg 	  output_address (VOIDmode, XEXP (x, 0));
   4802  1.1  mrg 	  return;
   4803  1.1  mrg 	}
   4804  1.1  mrg       else
   4805  1.1  mrg 	{
   4806  1.1  mrg 	  output_addr_const (file, x);
   4807  1.1  mrg 	  return;
   4808  1.1  mrg 	}
   4809  1.1  mrg       break;
   4810  1.1  mrg     }
   4811  1.1  mrg 
   4812  1.1  mrg   debug_rtx (x);
   4813  1.1  mrg   output_operand_lossage ("unable to print out operand yet; code == %d (%c)",
   4814  1.1  mrg 			  code, code);
   4815  1.1  mrg }
   4816  1.1  mrg 
   4817  1.1  mrg 
   4818  1.1  mrg /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
   4819  1.1  mrg static void
   4820  1.1  mrg tilepro_print_operand_address (FILE *file, machine_mode mode, rtx addr)
   4821  1.1  mrg {
   4822  1.1  mrg   if (GET_CODE (addr) == POST_DEC
   4823  1.1  mrg       || GET_CODE (addr) == POST_INC)
   4824  1.1  mrg     {
   4825  1.1  mrg       int offset = GET_MODE_SIZE (mode);
   4826  1.1  mrg 
   4827  1.1  mrg       gcc_assert (mode != VOIDmode);
   4828  1.1  mrg 
   4829  1.1  mrg       if (output_memory_autoinc_first)
   4830  1.1  mrg 	fprintf (file, "%s", reg_names[REGNO (XEXP (addr, 0))]);
   4831  1.1  mrg       else
   4832  1.1  mrg 	fprintf (file, "%d",
   4833  1.1  mrg 		 GET_CODE (addr) == POST_DEC ? -offset : offset);
   4834  1.1  mrg     }
   4835  1.1  mrg   else if (GET_CODE (addr) == POST_MODIFY)
   4836  1.1  mrg     {
   4837  1.1  mrg       gcc_assert (mode != VOIDmode);
   4838  1.1  mrg 
   4839  1.1  mrg       gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
   4840  1.1  mrg 
   4841  1.1  mrg       if (output_memory_autoinc_first)
   4842  1.1  mrg 	fprintf (file, "%s", reg_names[REGNO (XEXP (addr, 0))]);
   4843  1.1  mrg       else
   4844  1.1  mrg 	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
   4845  1.1  mrg 		 INTVAL (XEXP (XEXP (addr, 1), 1)));
   4846  1.1  mrg     }
   4847  1.1  mrg   else
   4848  1.1  mrg     tilepro_print_operand (file, addr, 'r');
   4849  1.1  mrg }
   4850  1.1  mrg 
   4851  1.1  mrg 
   4852  1.1  mrg /* Machine mode of current insn, for determining curly brace
   4853  1.1  mrg    placement.  */
   4854  1.1  mrg static machine_mode insn_mode;
   4855  1.1  mrg 
   4856  1.1  mrg 
   4857  1.1  mrg /* Implement FINAL_PRESCAN_INSN.  This is used to emit bundles.  */
   4858  1.1  mrg void
   4859  1.1  mrg tilepro_final_prescan_insn (rtx_insn *insn)
   4860  1.1  mrg {
   4861  1.1  mrg   /* Record this for tilepro_asm_output_opcode to examine.  */
   4862  1.1  mrg   insn_mode = GET_MODE (insn);
   4863  1.1  mrg }
   4864  1.1  mrg 
   4865  1.1  mrg 
   4866  1.1  mrg /* While emitting asm, are we currently inside '{' for a bundle? */
   4867  1.1  mrg static bool tilepro_in_bundle = false;
   4868  1.1  mrg 
   4869  1.1  mrg /* Implement ASM_OUTPUT_OPCODE.  Prepend/append curly braces as
   4870  1.1  mrg    appropriate given the bundling information recorded by
   4871  1.1  mrg    tilepro_gen_bundles.  */
   4872  1.1  mrg const char *
   4873  1.1  mrg tilepro_asm_output_opcode (FILE *stream, const char *code)
   4874  1.1  mrg {
   4875  1.1  mrg   bool pseudo = !strcmp (code, "pseudo");
   4876  1.1  mrg 
   4877  1.1  mrg   if (!tilepro_in_bundle && insn_mode == SImode)
   4878  1.1  mrg     {
   4879  1.1  mrg       /* Start a new bundle.  */
   4880  1.1  mrg       fprintf (stream, "{\n\t");
   4881  1.1  mrg       tilepro_in_bundle = true;
   4882  1.1  mrg     }
   4883  1.1  mrg 
   4884  1.1  mrg   if (tilepro_in_bundle && insn_mode == QImode)
   4885  1.1  mrg     {
   4886  1.1  mrg       /* Close an existing bundle.  */
   4887  1.1  mrg       static char buf[100];
   4888  1.1  mrg 
   4889  1.1  mrg       gcc_assert (strlen (code) + 3 + 1 < sizeof (buf));
   4890  1.1  mrg 
   4891  1.1  mrg       strcpy (buf, pseudo ? "" : code);
   4892  1.1  mrg       strcat (buf, "\n\t}");
   4893  1.1  mrg       tilepro_in_bundle = false;
   4894  1.1  mrg 
   4895  1.1  mrg       return buf;
   4896  1.1  mrg     }
   4897  1.1  mrg   else
   4898  1.1  mrg     {
   4899  1.1  mrg       return pseudo ? "" : code;
   4900  1.1  mrg     }
   4901  1.1  mrg }
   4902  1.1  mrg 
   4903  1.1  mrg 
   4904  1.1  mrg /* Output assembler code to FILE to increment profiler label # LABELNO
   4905  1.1  mrg    for profiling a function entry.  */
   4906  1.1  mrg void
   4907  1.1  mrg tilepro_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
   4908  1.1  mrg {
   4909  1.1  mrg   if (tilepro_in_bundle)
   4910  1.1  mrg     {
   4911  1.1  mrg       fprintf (file, "\t}\n");
   4912  1.1  mrg     }
   4913  1.1  mrg 
   4914  1.1  mrg   if (flag_pic)
   4915  1.1  mrg     {
   4916  1.1  mrg       fprintf (file,
   4917  1.1  mrg 	       "\t{\n"
   4918  1.1  mrg 	       "\tmove\tr10, lr\n"
   4919  1.1  mrg 	       "\tjal\tplt(%s)\n"
   4920  1.1  mrg 	       "\t}\n", MCOUNT_NAME);
   4921  1.1  mrg     }
   4922  1.1  mrg   else
   4923  1.1  mrg     {
   4924  1.1  mrg       fprintf (file,
   4925  1.1  mrg 	       "\t{\n"
   4926  1.1  mrg 	       "\tmove\tr10, lr\n"
   4927  1.1  mrg 	       "\tjal\t%s\n"
   4928  1.1  mrg 	       "\t}\n", MCOUNT_NAME);
   4929  1.1  mrg     }
   4930  1.1  mrg 
   4931  1.1  mrg   tilepro_in_bundle = false;
   4932  1.1  mrg }
   4933  1.1  mrg 
   4934  1.1  mrg 
   4935  1.1  mrg /* Implement TARGET_ASM_FILE_END.  */
   4936  1.1  mrg static void
   4937  1.1  mrg tilepro_file_end (void)
   4938  1.1  mrg {
   4939  1.1  mrg   if (NEED_INDICATE_EXEC_STACK)
   4940  1.1  mrg     file_end_indicate_exec_stack ();
   4941  1.1  mrg }
   4942  1.1  mrg 
   4943  1.1  mrg 
   4944  1.1  mrg #undef  TARGET_HAVE_TLS
   4945  1.1  mrg #define TARGET_HAVE_TLS HAVE_AS_TLS
   4946  1.1  mrg 
   4947  1.1  mrg #undef  TARGET_OPTION_OVERRIDE
   4948  1.1  mrg #define TARGET_OPTION_OVERRIDE tilepro_option_override
   4949  1.1  mrg 
   4950  1.1  mrg #ifdef TARGET_THREAD_SSP_OFFSET
   4951  1.1  mrg #undef TARGET_STACK_PROTECT_GUARD
   4952  1.1  mrg #define TARGET_STACK_PROTECT_GUARD hook_tree_void_null
   4953  1.1  mrg #endif
   4954  1.1  mrg 
   4955  1.1  mrg #undef  TARGET_SCALAR_MODE_SUPPORTED_P
   4956  1.1  mrg #define TARGET_SCALAR_MODE_SUPPORTED_P tilepro_scalar_mode_supported_p
   4957  1.1  mrg 
   4958  1.1  mrg #undef  TARGET_VECTOR_MODE_SUPPORTED_P
   4959  1.1  mrg #define TARGET_VECTOR_MODE_SUPPORTED_P tile_vector_mode_supported_p
   4960  1.1  mrg 
   4961  1.1  mrg #undef  TARGET_CANNOT_FORCE_CONST_MEM
   4962  1.1  mrg #define TARGET_CANNOT_FORCE_CONST_MEM tilepro_cannot_force_const_mem
   4963  1.1  mrg 
   4964  1.1  mrg #undef  TARGET_FUNCTION_OK_FOR_SIBCALL
   4965  1.1  mrg #define TARGET_FUNCTION_OK_FOR_SIBCALL tilepro_function_ok_for_sibcall
   4966  1.1  mrg 
   4967  1.1  mrg #undef  TARGET_PASS_BY_REFERENCE
   4968  1.1  mrg #define TARGET_PASS_BY_REFERENCE tilepro_pass_by_reference
   4969  1.1  mrg 
   4970  1.1  mrg #undef  TARGET_RETURN_IN_MEMORY
   4971  1.1  mrg #define TARGET_RETURN_IN_MEMORY tilepro_return_in_memory
   4972  1.1  mrg 
   4973  1.1  mrg #undef  TARGET_FUNCTION_ARG_BOUNDARY
   4974  1.1  mrg #define TARGET_FUNCTION_ARG_BOUNDARY tilepro_function_arg_boundary
   4975  1.1  mrg 
   4976  1.1  mrg #undef  TARGET_FUNCTION_ARG
   4977  1.1  mrg #define TARGET_FUNCTION_ARG tilepro_function_arg
   4978  1.1  mrg 
   4979  1.1  mrg #undef  TARGET_FUNCTION_ARG_ADVANCE
   4980  1.1  mrg #define TARGET_FUNCTION_ARG_ADVANCE tilepro_function_arg_advance
   4981  1.1  mrg 
   4982  1.1  mrg #undef  TARGET_FUNCTION_VALUE
   4983  1.1  mrg #define TARGET_FUNCTION_VALUE tilepro_function_value
   4984  1.1  mrg 
   4985  1.1  mrg #undef  TARGET_LIBCALL_VALUE
   4986  1.1  mrg #define TARGET_LIBCALL_VALUE tilepro_libcall_value
   4987  1.1  mrg 
   4988  1.1  mrg #undef  TARGET_FUNCTION_VALUE_REGNO_P
   4989  1.1  mrg #define TARGET_FUNCTION_VALUE_REGNO_P tilepro_function_value_regno_p
   4990  1.1  mrg 
   4991  1.1  mrg #undef  TARGET_PROMOTE_FUNCTION_MODE
   4992  1.1  mrg #define TARGET_PROMOTE_FUNCTION_MODE \
   4993  1.1  mrg   default_promote_function_mode_always_promote
   4994  1.1  mrg 
   4995  1.1  mrg #undef  TARGET_PROMOTE_PROTOTYPES
   4996  1.1  mrg #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
   4997  1.1  mrg 
   4998  1.1  mrg #undef  TARGET_BUILD_BUILTIN_VA_LIST
   4999  1.1  mrg #define TARGET_BUILD_BUILTIN_VA_LIST tilepro_build_builtin_va_list
   5000  1.1  mrg 
   5001  1.1  mrg #undef  TARGET_EXPAND_BUILTIN_VA_START
   5002  1.1  mrg #define TARGET_EXPAND_BUILTIN_VA_START tilepro_va_start
   5003  1.1  mrg 
   5004  1.1  mrg #undef  TARGET_SETUP_INCOMING_VARARGS
   5005  1.1  mrg #define TARGET_SETUP_INCOMING_VARARGS tilepro_setup_incoming_varargs
   5006  1.1  mrg 
   5007  1.1  mrg #undef  TARGET_GIMPLIFY_VA_ARG_EXPR
   5008  1.1  mrg #define TARGET_GIMPLIFY_VA_ARG_EXPR tilepro_gimplify_va_arg_expr
   5009  1.1  mrg 
   5010  1.1  mrg #undef  TARGET_RTX_COSTS
   5011  1.1  mrg #define TARGET_RTX_COSTS tilepro_rtx_costs
   5012  1.1  mrg 
   5013  1.1  mrg /* Limit to what we can reach in one addli.  */
   5014  1.1  mrg #undef  TARGET_MIN_ANCHOR_OFFSET
   5015  1.1  mrg #define TARGET_MIN_ANCHOR_OFFSET -32768
   5016  1.1  mrg #undef  TARGET_MAX_ANCHOR_OFFSET
   5017  1.1  mrg #define TARGET_MAX_ANCHOR_OFFSET 32767
   5018  1.1  mrg 
   5019  1.1  mrg #undef  TARGET_LEGITIMATE_CONSTANT_P
   5020  1.1  mrg #define TARGET_LEGITIMATE_CONSTANT_P tilepro_legitimate_constant_p
   5021  1.1  mrg 
   5022  1.1  mrg #undef TARGET_LRA_P
   5023  1.1  mrg #define TARGET_LRA_P hook_bool_void_false
   5024  1.1  mrg 
   5025  1.1  mrg #undef  TARGET_LEGITIMATE_ADDRESS_P
   5026  1.1  mrg #define TARGET_LEGITIMATE_ADDRESS_P tilepro_legitimate_address_p
   5027  1.1  mrg 
   5028  1.1  mrg #undef  TARGET_LEGITIMIZE_ADDRESS
   5029  1.1  mrg #define TARGET_LEGITIMIZE_ADDRESS tilepro_legitimize_address
   5030  1.1  mrg 
   5031  1.1  mrg #undef  TARGET_DELEGITIMIZE_ADDRESS
   5032  1.1  mrg #define TARGET_DELEGITIMIZE_ADDRESS tilepro_delegitimize_address
   5033  1.1  mrg 
   5034  1.1  mrg #undef  TARGET_INIT_BUILTINS
   5035  1.1  mrg #define TARGET_INIT_BUILTINS  tilepro_init_builtins
   5036  1.1  mrg 
   5037  1.1  mrg #undef  TARGET_BUILTIN_DECL
   5038  1.1  mrg #define TARGET_BUILTIN_DECL tilepro_builtin_decl
   5039  1.1  mrg 
   5040  1.1  mrg #undef  TARGET_EXPAND_BUILTIN
   5041  1.1  mrg #define TARGET_EXPAND_BUILTIN tilepro_expand_builtin
   5042  1.1  mrg 
   5043  1.1  mrg #undef  TARGET_CONDITIONAL_REGISTER_USAGE
   5044  1.1  mrg #define TARGET_CONDITIONAL_REGISTER_USAGE tilepro_conditional_register_usage
   5045  1.1  mrg 
   5046  1.1  mrg #undef  TARGET_FRAME_POINTER_REQUIRED
   5047  1.1  mrg #define TARGET_FRAME_POINTER_REQUIRED tilepro_frame_pointer_required
   5048  1.1  mrg 
   5049  1.1  mrg #undef  TARGET_DELAY_SCHED2
   5050  1.1  mrg #define TARGET_DELAY_SCHED2 true
   5051  1.1  mrg 
   5052  1.1  mrg #undef  TARGET_DELAY_VARTRACK
   5053  1.1  mrg #define TARGET_DELAY_VARTRACK true
   5054  1.1  mrg 
   5055  1.1  mrg #undef  TARGET_SCHED_ISSUE_RATE
   5056  1.1  mrg #define TARGET_SCHED_ISSUE_RATE tilepro_issue_rate
   5057  1.1  mrg 
   5058  1.1  mrg #undef  TARGET_SCHED_ADJUST_COST
   5059  1.1  mrg #define TARGET_SCHED_ADJUST_COST tilepro_sched_adjust_cost
   5060  1.1  mrg 
   5061  1.1  mrg #undef  TARGET_MACHINE_DEPENDENT_REORG
   5062  1.1  mrg #define TARGET_MACHINE_DEPENDENT_REORG tilepro_reorg
   5063  1.1  mrg 
   5064  1.1  mrg #undef  TARGET_ASM_CAN_OUTPUT_MI_THUNK
   5065  1.1  mrg #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
   5066  1.1  mrg   hook_bool_const_tree_hwi_hwi_const_tree_true
   5067  1.1  mrg 
   5068  1.1  mrg #undef  TARGET_ASM_OUTPUT_MI_THUNK
   5069  1.1  mrg #define TARGET_ASM_OUTPUT_MI_THUNK tilepro_asm_output_mi_thunk
   5070  1.1  mrg 
   5071  1.1  mrg #undef  TARGET_ASM_TRAMPOLINE_TEMPLATE
   5072  1.1  mrg #define TARGET_ASM_TRAMPOLINE_TEMPLATE tilepro_asm_trampoline_template
   5073  1.1  mrg 
   5074  1.1  mrg #undef  TARGET_TRAMPOLINE_INIT
   5075  1.1  mrg #define TARGET_TRAMPOLINE_INIT tilepro_trampoline_init
   5076  1.1  mrg 
   5077  1.1  mrg #undef  TARGET_PRINT_OPERAND
   5078  1.1  mrg #define TARGET_PRINT_OPERAND tilepro_print_operand
   5079  1.1  mrg 
   5080  1.1  mrg #undef  TARGET_PRINT_OPERAND_ADDRESS
   5081  1.1  mrg #define TARGET_PRINT_OPERAND_ADDRESS tilepro_print_operand_address
   5082  1.1  mrg 
   5083  1.1  mrg #undef  TARGET_ASM_FILE_END
   5084           #define TARGET_ASM_FILE_END tilepro_file_end
   5085           
   5086           #undef  TARGET_CAN_USE_DOLOOP_P
   5087           #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
   5088           
   5089           #undef  TARGET_CONSTANT_ALIGNMENT
   5090           #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
   5091           
   5092           struct gcc_target targetm = TARGET_INITIALIZER;
   5093           
   5094           #include "gt-tilepro.h"
   5095