Home | History | Annotate | Line # | Download | only in bfin
bfin.cc revision 1.1
      1 /* The Blackfin code generation auxiliary output file.
      2    Copyright (C) 2005-2022 Free Software Foundation, Inc.
      3    Contributed by Analog Devices.
      4 
      5    This file is part of GCC.
      6 
      7    GCC is free software; you can redistribute it and/or modify it
      8    under the terms of the GNU General Public License as published
      9    by the Free Software Foundation; either version 3, or (at your
     10    option) any later version.
     11 
     12    GCC is distributed in the hope that it will be useful, but WITHOUT
     13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15    License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GCC; see the file COPYING3.  If not see
     19    <http://www.gnu.org/licenses/>.  */
     20 
     21 #define IN_TARGET_CODE 1
     22 
     23 #include "config.h"
     24 #include "system.h"
     25 #include "coretypes.h"
     26 #include "backend.h"
     27 #include "target.h"
     28 #include "rtl.h"
     29 #include "tree.h"
     30 #include "stringpool.h"
     31 #include "attribs.h"
     32 #include "cfghooks.h"
     33 #include "df.h"
     34 #include "memmodel.h"
     35 #include "tm_p.h"
     36 #include "optabs.h"
     37 #include "regs.h"
     38 #include "emit-rtl.h"
     39 #include "recog.h"
     40 #include "cgraph.h"
     41 #include "diagnostic-core.h"
     42 #include "output.h"
     43 #include "insn-attr.h"
     44 #include "varasm.h"
     45 #include "calls.h"
     46 #include "explow.h"
     47 #include "expr.h"
     48 #include "cfgrtl.h"
     49 #include "langhooks.h"
     50 #include "tm-constrs.h"
     51 #include "gt-bfin.h"
     52 #include "sel-sched.h"
     53 #include "hw-doloop.h"
     54 #include "dumpfile.h"
     55 #include "builtins.h"
     56 #include "opts.h"
     57 
     58 /* This file should be included last.  */
     59 #include "target-def.h"
     60 
     61 /* A C structure for machine-specific, per-function data.
     62    This is added to the cfun structure.  */
     63 struct GTY(()) machine_function
     64 {
     65   /* Set if we are notified by the doloop pass that a hardware loop
     66      was created.  */
     67   int has_hardware_loops;
     68 
     69   /* Set if we create a memcpy pattern that uses loop registers.  */
     70   int has_loopreg_clobber;
     71 };
     72 
     73 /* RTX for condition code flag register and RETS register */
     74 extern GTY(()) rtx bfin_cc_rtx;
     75 extern GTY(()) rtx bfin_rets_rtx;
     76 rtx bfin_cc_rtx, bfin_rets_rtx;
     77 
     78 int max_arg_registers = 0;
     79 
     80 /* Arrays used when emitting register names.  */
     81 const char *short_reg_names[]  =  SHORT_REGISTER_NAMES;
     82 const char *high_reg_names[]   =  HIGH_REGISTER_NAMES;
     83 const char *dregs_pair_names[] =  DREGS_PAIR_NAMES;
     84 const char *byte_reg_names[]   =  BYTE_REGISTER_NAMES;
     85 
     86 static int arg_regs[] = FUNCTION_ARG_REGISTERS;
     87 static int ret_regs[] = FUNCTION_RETURN_REGISTERS;
     88 
     89 int splitting_for_sched, splitting_loops;
     90 
     91 static void
     92 bfin_globalize_label (FILE *stream, const char *name)
     93 {
     94   fputs (".global ", stream);
     95   assemble_name (stream, name);
     96   fputc (';',stream);
     97   fputc ('\n',stream);
     98 }
     99 
    100 static void
    101 output_file_start (void)
    102 {
    103   FILE *file = asm_out_file;
    104   int i;
    105 
    106   fprintf (file, ".file \"%s\";\n", LOCATION_FILE (input_location));
    107 
    108   for (i = 0; arg_regs[i] >= 0; i++)
    109     ;
    110   max_arg_registers = i;	/* how many arg reg used  */
    111 }
    112 
    113 /* Examine machine-dependent attributes of function type FUNTYPE and return its
    114    type.  See the definition of E_FUNKIND.  */
    115 
    116 static e_funkind
    117 funkind (const_tree funtype)
    118 {
    119   tree attrs = TYPE_ATTRIBUTES (funtype);
    120   if (lookup_attribute ("interrupt_handler", attrs))
    121     return INTERRUPT_HANDLER;
    122   else if (lookup_attribute ("exception_handler", attrs))
    123     return EXCPT_HANDLER;
    124   else if (lookup_attribute ("nmi_handler", attrs))
    125     return NMI_HANDLER;
    126   else
    127     return SUBROUTINE;
    128 }
    129 
    130 /* Legitimize PIC addresses.  If the address is already position-independent,
    132    we return ORIG.  Newly generated position-independent addresses go into a
    133    reg.  This is REG if nonzero, otherwise we allocate register(s) as
    134    necessary.  PICREG is the register holding the pointer to the PIC offset
    135    table.  */
    136 
    137 static rtx
    138 legitimize_pic_address (rtx orig, rtx reg, rtx picreg)
    139 {
    140   rtx addr = orig;
    141   rtx new_rtx = orig;
    142 
    143   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
    144     {
    145       int unspec;
    146       rtx tmp;
    147 
    148       if (TARGET_ID_SHARED_LIBRARY)
    149 	unspec = UNSPEC_MOVE_PIC;
    150       else if (GET_CODE (addr) == SYMBOL_REF
    151 	       && SYMBOL_REF_FUNCTION_P (addr))
    152 	unspec = UNSPEC_FUNCDESC_GOT17M4;
    153       else
    154 	unspec = UNSPEC_MOVE_FDPIC;
    155 
    156       if (reg == 0)
    157 	{
    158 	  gcc_assert (can_create_pseudo_p ());
    159 	  reg = gen_reg_rtx (Pmode);
    160 	}
    161 
    162       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), unspec);
    163       new_rtx = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, picreg, tmp));
    164 
    165       emit_move_insn (reg, new_rtx);
    166       if (picreg == pic_offset_table_rtx)
    167 	crtl->uses_pic_offset_table = 1;
    168       return reg;
    169     }
    170 
    171   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
    172     {
    173       rtx base;
    174 
    175       if (GET_CODE (addr) == CONST)
    176 	{
    177 	  addr = XEXP (addr, 0);
    178 	  gcc_assert (GET_CODE (addr) == PLUS);
    179 	}
    180 
    181       if (XEXP (addr, 0) == picreg)
    182 	return orig;
    183 
    184       if (reg == 0)
    185 	{
    186 	  gcc_assert (can_create_pseudo_p ());
    187 	  reg = gen_reg_rtx (Pmode);
    188 	}
    189 
    190       base = legitimize_pic_address (XEXP (addr, 0), reg, picreg);
    191       addr = legitimize_pic_address (XEXP (addr, 1),
    192 				     base == reg ? NULL_RTX : reg,
    193 				     picreg);
    194 
    195       if (GET_CODE (addr) == CONST_INT)
    196 	{
    197 	  gcc_assert (! reload_in_progress && ! reload_completed);
    198 	  addr = force_reg (Pmode, addr);
    199 	}
    200 
    201       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
    202 	{
    203 	  base = gen_rtx_PLUS (Pmode, base, XEXP (addr, 0));
    204 	  addr = XEXP (addr, 1);
    205 	}
    206 
    207       return gen_rtx_PLUS (Pmode, base, addr);
    208     }
    209 
    210   return new_rtx;
    211 }
    212 
    213 /* Stack frame layout. */
    215 
    216 /* For a given REGNO, determine whether it must be saved in the function
    217    prologue.  IS_INTHANDLER specifies whether we're generating a normal
    218    prologue or an interrupt/exception one.  */
    219 static bool
    220 must_save_p (bool is_inthandler, unsigned regno)
    221 {
    222   if (D_REGNO_P (regno))
    223     {
    224       bool is_eh_return_reg = false;
    225       if (crtl->calls_eh_return)
    226 	{
    227 	  unsigned j;
    228 	  for (j = 0; ; j++)
    229 	    {
    230 	      unsigned test = EH_RETURN_DATA_REGNO (j);
    231 	      if (test == INVALID_REGNUM)
    232 		break;
    233 	      if (test == regno)
    234 		is_eh_return_reg = true;
    235 	    }
    236 	}
    237 
    238       return (is_eh_return_reg
    239 	      || (df_regs_ever_live_p (regno)
    240 		  && !fixed_regs[regno]
    241 		  && (is_inthandler || !call_used_or_fixed_reg_p (regno))));
    242     }
    243   else if (P_REGNO_P (regno))
    244     {
    245       return ((df_regs_ever_live_p (regno)
    246 	       && !fixed_regs[regno]
    247 	       && (is_inthandler || !call_used_or_fixed_reg_p (regno)))
    248 	      || (is_inthandler
    249 		  && (ENABLE_WA_05000283 || ENABLE_WA_05000315)
    250 		  && regno == REG_P5)
    251 	      || (!TARGET_FDPIC
    252 		  && regno == PIC_OFFSET_TABLE_REGNUM
    253 		  && (crtl->uses_pic_offset_table
    254 		      || (TARGET_ID_SHARED_LIBRARY && !crtl->is_leaf))));
    255     }
    256   else
    257     return ((is_inthandler || !call_used_or_fixed_reg_p (regno))
    258 	    && (df_regs_ever_live_p (regno)
    259 		|| (!leaf_function_p () && call_used_or_fixed_reg_p (regno))));
    260 
    261 }
    262 
    263 /* Compute the number of DREGS to save with a push_multiple operation.
    264    This could include registers that aren't modified in the function,
    265    since push_multiple only takes a range of registers.
    266    If IS_INTHANDLER, then everything that is live must be saved, even
    267    if normally call-clobbered.
    268    If CONSECUTIVE, return the number of registers we can save in one
    269    instruction with a push/pop multiple instruction.  */
    270 
    271 static int
    272 n_dregs_to_save (bool is_inthandler, bool consecutive)
    273 {
    274   int count = 0;
    275   unsigned i;
    276 
    277   for (i = REG_R7 + 1; i-- != REG_R0;)
    278     {
    279       if (must_save_p (is_inthandler, i))
    280 	count++;
    281       else if (consecutive)
    282 	return count;
    283     }
    284   return count;
    285 }
    286 
    287 /* Like n_dregs_to_save, but compute number of PREGS to save.  */
    288 
    289 static int
    290 n_pregs_to_save (bool is_inthandler, bool consecutive)
    291 {
    292   int count = 0;
    293   unsigned i;
    294 
    295   for (i = REG_P5 + 1; i-- != REG_P0;)
    296     if (must_save_p (is_inthandler, i))
    297       count++;
    298     else if (consecutive)
    299       return count;
    300   return count;
    301 }
    302 
    303 /* Determine if we are going to save the frame pointer in the prologue.  */
    304 
    305 static bool
    306 must_save_fp_p (void)
    307 {
    308   return df_regs_ever_live_p (REG_FP);
    309 }
    310 
    311 /* Determine if we are going to save the RETS register.  */
    312 static bool
    313 must_save_rets_p (void)
    314 {
    315   return df_regs_ever_live_p (REG_RETS);
    316 }
    317 
    318 static bool
    319 stack_frame_needed_p (void)
    320 {
    321   /* EH return puts a new return address into the frame using an
    322      address relative to the frame pointer.  */
    323   if (crtl->calls_eh_return)
    324     return true;
    325   return frame_pointer_needed;
    326 }
    327 
    328 /* Emit code to save registers in the prologue.  SAVEALL is nonzero if we
    329    must save all registers; this is used for interrupt handlers.
    330    SPREG contains (reg:SI REG_SP).  IS_INTHANDLER is true if we're doing
    331    this for an interrupt (or exception) handler.  */
    332 
    333 static void
    334 expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler)
    335 {
    336   rtx predec1 = gen_rtx_PRE_DEC (SImode, spreg);
    337   rtx predec = gen_rtx_MEM (SImode, predec1);
    338   int ndregs = saveall ? 8 : n_dregs_to_save (is_inthandler, false);
    339   int npregs = saveall ? 6 : n_pregs_to_save (is_inthandler, false);
    340   int ndregs_consec = saveall ? 8 : n_dregs_to_save (is_inthandler, true);
    341   int npregs_consec = saveall ? 6 : n_pregs_to_save (is_inthandler, true);
    342   int dregno, pregno;
    343   int total_consec = ndregs_consec + npregs_consec;
    344   int i, d_to_save;
    345 
    346   if (saveall || is_inthandler)
    347     {
    348       rtx_insn *insn = emit_move_insn (predec, gen_rtx_REG (SImode, REG_ASTAT));
    349 
    350       RTX_FRAME_RELATED_P (insn) = 1;
    351       for (dregno = REG_LT0; dregno <= REG_LB1; dregno++)
    352 	if (! crtl->is_leaf
    353 	    || cfun->machine->has_hardware_loops
    354 	    || cfun->machine->has_loopreg_clobber
    355 	    || (ENABLE_WA_05000257
    356 		&& (dregno == REG_LC0 || dregno == REG_LC1)))
    357 	  {
    358 	    insn = emit_move_insn (predec, gen_rtx_REG (SImode, dregno));
    359 	    RTX_FRAME_RELATED_P (insn) = 1;
    360 	  }
    361     }
    362 
    363   if (total_consec != 0)
    364     {
    365       rtx_insn *insn;
    366       rtx val = GEN_INT (-total_consec * 4);
    367       rtx pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_consec + 2));
    368 
    369       XVECEXP (pat, 0, 0) = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, val),
    370 					    UNSPEC_PUSH_MULTIPLE);
    371       XVECEXP (pat, 0, total_consec + 1) = gen_rtx_SET (spreg,
    372 							gen_rtx_PLUS (Pmode,
    373 								      spreg,
    374 								      val));
    375       RTX_FRAME_RELATED_P (XVECEXP (pat, 0, total_consec + 1)) = 1;
    376       d_to_save = ndregs_consec;
    377       dregno = REG_R7 + 1 - ndregs_consec;
    378       pregno = REG_P5 + 1 - npregs_consec;
    379       for (i = 0; i < total_consec; i++)
    380 	{
    381 	  rtx memref = gen_rtx_MEM (word_mode,
    382 				    gen_rtx_PLUS (Pmode, spreg,
    383 						  GEN_INT (- i * 4 - 4)));
    384 	  rtx subpat;
    385 	  if (d_to_save > 0)
    386 	    {
    387 	      subpat = gen_rtx_SET (memref, gen_rtx_REG (word_mode, dregno++));
    388 	      d_to_save--;
    389 	    }
    390 	  else
    391 	    {
    392 	      subpat = gen_rtx_SET (memref, gen_rtx_REG (word_mode, pregno++));
    393 	    }
    394 	  XVECEXP (pat, 0, i + 1) = subpat;
    395 	  RTX_FRAME_RELATED_P (subpat) = 1;
    396 	}
    397       insn = emit_insn (pat);
    398       RTX_FRAME_RELATED_P (insn) = 1;
    399     }
    400 
    401   for (dregno = REG_R0; ndregs != ndregs_consec; dregno++)
    402     {
    403       if (must_save_p (is_inthandler, dregno))
    404 	{
    405 	  rtx_insn *insn =
    406 	    emit_move_insn (predec, gen_rtx_REG (word_mode, dregno));
    407 	  RTX_FRAME_RELATED_P (insn) = 1;
    408 	  ndregs--;
    409 	}
    410     }
    411   for (pregno = REG_P0; npregs != npregs_consec; pregno++)
    412     {
    413       if (must_save_p (is_inthandler, pregno))
    414 	{
    415 	  rtx_insn *insn =
    416 	    emit_move_insn (predec, gen_rtx_REG (word_mode, pregno));
    417 	  RTX_FRAME_RELATED_P (insn) = 1;
    418 	  npregs--;
    419 	}
    420     }
    421   for (i = REG_P7 + 1; i < REG_CC; i++)
    422     if (saveall
    423 	|| (is_inthandler
    424 	    && (df_regs_ever_live_p (i)
    425 		|| (!leaf_function_p () && call_used_or_fixed_reg_p (i)))))
    426       {
    427 	rtx_insn *insn;
    428 	if (i == REG_A0 || i == REG_A1)
    429 	  insn = emit_move_insn (gen_rtx_MEM (PDImode, predec1),
    430 				 gen_rtx_REG (PDImode, i));
    431 	else
    432 	  insn = emit_move_insn (predec, gen_rtx_REG (SImode, i));
    433 	RTX_FRAME_RELATED_P (insn) = 1;
    434       }
    435 }
    436 
    437 /* Emit code to restore registers in the epilogue.  SAVEALL is nonzero if we
    438    must save all registers; this is used for interrupt handlers.
    439    SPREG contains (reg:SI REG_SP).  IS_INTHANDLER is true if we're doing
    440    this for an interrupt (or exception) handler.  */
    441 
    442 static void
    443 expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler)
    444 {
    445   rtx postinc1 = gen_rtx_POST_INC (SImode, spreg);
    446   rtx postinc = gen_rtx_MEM (SImode, postinc1);
    447 
    448   int ndregs = saveall ? 8 : n_dregs_to_save (is_inthandler, false);
    449   int npregs = saveall ? 6 : n_pregs_to_save (is_inthandler, false);
    450   int ndregs_consec = saveall ? 8 : n_dregs_to_save (is_inthandler, true);
    451   int npregs_consec = saveall ? 6 : n_pregs_to_save (is_inthandler, true);
    452   int total_consec = ndregs_consec + npregs_consec;
    453   int i, regno;
    454   rtx_insn *insn;
    455 
    456   /* A slightly crude technique to stop flow from trying to delete "dead"
    457      insns.  */
    458   MEM_VOLATILE_P (postinc) = 1;
    459 
    460   for (i = REG_CC - 1; i > REG_P7; i--)
    461     if (saveall
    462 	|| (is_inthandler
    463 	    && (df_regs_ever_live_p (i)
    464 		|| (!leaf_function_p () && call_used_or_fixed_reg_p (i)))))
    465       {
    466 	if (i == REG_A0 || i == REG_A1)
    467 	  {
    468 	    rtx mem = gen_rtx_MEM (PDImode, postinc1);
    469 	    MEM_VOLATILE_P (mem) = 1;
    470 	    emit_move_insn (gen_rtx_REG (PDImode, i), mem);
    471 	  }
    472 	else
    473 	  emit_move_insn (gen_rtx_REG (SImode, i), postinc);
    474       }
    475 
    476   regno = REG_P5 - npregs_consec;
    477   for (; npregs != npregs_consec; regno--)
    478     {
    479       if (must_save_p (is_inthandler, regno))
    480 	{
    481 	  emit_move_insn (gen_rtx_REG (word_mode, regno), postinc);
    482 	  npregs--;
    483 	}
    484     }
    485   regno = REG_R7 - ndregs_consec;
    486   for (; ndregs != ndregs_consec; regno--)
    487     {
    488       if (must_save_p (is_inthandler, regno))
    489 	{
    490 	  emit_move_insn (gen_rtx_REG (word_mode, regno), postinc);
    491 	  ndregs--;
    492 	}
    493     }
    494 
    495   if (total_consec != 0)
    496     {
    497       rtx pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_consec + 1));
    498       XVECEXP (pat, 0, 0)
    499 	= gen_rtx_SET (spreg, gen_rtx_PLUS (Pmode, spreg,
    500 					    GEN_INT (total_consec * 4)));
    501 
    502       if (npregs_consec > 0)
    503 	regno = REG_P5 + 1;
    504       else
    505 	regno = REG_R7 + 1;
    506 
    507       for (i = 0; i < total_consec; i++)
    508 	{
    509 	  rtx addr = (i > 0
    510 		      ? gen_rtx_PLUS (Pmode, spreg, GEN_INT (i * 4))
    511 		      : spreg);
    512 	  rtx memref = gen_rtx_MEM (word_mode, addr);
    513 
    514 	  regno--;
    515 	  XVECEXP (pat, 0, i + 1)
    516 	    = gen_rtx_SET (gen_rtx_REG (word_mode, regno), memref);
    517 
    518 	  if (npregs_consec > 0)
    519 	    {
    520 	      if (--npregs_consec == 0)
    521 		regno = REG_R7 + 1;
    522 	    }
    523 	}
    524 
    525       insn = emit_insn (pat);
    526       RTX_FRAME_RELATED_P (insn) = 1;
    527     }
    528   if (saveall || is_inthandler)
    529     {
    530       for (regno = REG_LB1; regno >= REG_LT0; regno--)
    531 	if (! crtl->is_leaf
    532 	    || cfun->machine->has_hardware_loops
    533 	    || cfun->machine->has_loopreg_clobber
    534 	    || (ENABLE_WA_05000257 && (regno == REG_LC0 || regno == REG_LC1)))
    535 	  emit_move_insn (gen_rtx_REG (SImode, regno), postinc);
    536 
    537       emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc);
    538     }
    539 }
    540 
    541 /* Perform any needed actions needed for a function that is receiving a
    542    variable number of arguments.
    543 
    544    CUM is as above.
    545 
    546    ARG is the last named argument.
    547 
    548    PRETEND_SIZE is a variable that should be set to the amount of stack
    549    that must be pushed by the prolog to pretend that our caller pushed
    550    it.
    551 
    552    Normally, this macro will push all remaining incoming registers on the
    553    stack and set PRETEND_SIZE to the length of the registers pushed.
    554 
    555    Blackfin specific :
    556    - VDSP C compiler manual (our ABI) says that a variable args function
    557      should save the R0, R1 and R2 registers in the stack.
    558    - The caller will always leave space on the stack for the
    559      arguments that are passed in registers, so we dont have
    560      to leave any extra space.
    561    - now, the vastart pointer can access all arguments from the stack.  */
    562 
    563 static void
    564 setup_incoming_varargs (cumulative_args_t cum,
    565 			const function_arg_info &, int *pretend_size,
    566 			int no_rtl)
    567 {
    568   rtx mem;
    569   int i;
    570 
    571   if (no_rtl)
    572     return;
    573 
    574   /* The move for named arguments will be generated automatically by the
    575      compiler.  We need to generate the move rtx for the unnamed arguments
    576      if they are in the first 3 words.  We assume at least 1 named argument
    577      exists, so we never generate [ARGP] = R0 here.  */
    578 
    579   for (i = get_cumulative_args (cum)->words + 1; i < max_arg_registers; i++)
    580     {
    581       mem = gen_rtx_MEM (Pmode,
    582 			 plus_constant (Pmode, arg_pointer_rtx,
    583 					(i * UNITS_PER_WORD)));
    584       emit_move_insn (mem, gen_rtx_REG (Pmode, i));
    585     }
    586 
    587   *pretend_size = 0;
    588 }
    589 
    590 /* Value should be nonzero if functions must have frame pointers.
    591    Zero means the frame pointer need not be set up (and parms may
    592    be accessed via the stack pointer) in functions that seem suitable.  */
    593 
    594 static bool
    595 bfin_frame_pointer_required (void)
    596 {
    597   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
    598 
    599   if (fkind != SUBROUTINE)
    600     return true;
    601 
    602   /* We turn on -fomit-frame-pointer if -momit-leaf-frame-pointer is used,
    603      so we have to override it for non-leaf functions.  */
    604   if (TARGET_OMIT_LEAF_FRAME_POINTER && ! crtl->is_leaf)
    605     return true;
    606 
    607   return false;
    608 }
    609 
    610 /* Return the number of registers pushed during the prologue.  */
    611 
    612 static int
    613 n_regs_saved_by_prologue (void)
    614 {
    615   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
    616   bool is_inthandler = fkind != SUBROUTINE;
    617   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
    618   bool all = (lookup_attribute ("saveall", attrs) != NULL_TREE
    619 	      || (is_inthandler && !crtl->is_leaf));
    620   int ndregs = all ? 8 : n_dregs_to_save (is_inthandler, false);
    621   int npregs = all ? 6 : n_pregs_to_save (is_inthandler, false);
    622   int n = ndregs + npregs;
    623   int i;
    624 
    625   if (all || stack_frame_needed_p ())
    626     n += 2;
    627   else
    628     {
    629       if (must_save_fp_p ())
    630 	n++;
    631       if (must_save_rets_p ())
    632 	n++;
    633     }
    634 
    635   if (fkind != SUBROUTINE || all)
    636     {
    637       /* Increment once for ASTAT.  */
    638       n++;
    639       if (! crtl->is_leaf
    640 	  || cfun->machine->has_hardware_loops
    641 	  || cfun->machine->has_loopreg_clobber)
    642 	{
    643 	  n += 6;
    644 	}
    645     }
    646 
    647   if (fkind != SUBROUTINE)
    648     {
    649       /* RETE/X/N.  */
    650       if (lookup_attribute ("nesting", attrs))
    651 	n++;
    652     }
    653 
    654   for (i = REG_P7 + 1; i < REG_CC; i++)
    655     if (all
    656 	|| (fkind != SUBROUTINE
    657 	    && (df_regs_ever_live_p (i)
    658 		|| (!leaf_function_p () && call_used_or_fixed_reg_p (i)))))
    659       n += i == REG_A0 || i == REG_A1 ? 2 : 1;
    660 
    661   return n;
    662 }
    663 
    664 /* Given FROM and TO register numbers, say whether this elimination is
    665    allowed.  Frame pointer elimination is automatically handled.
    666 
    667    All other eliminations are valid.  */
    668 
    669 static bool
    670 bfin_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
    671 {
    672   return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true);
    673 }
    674 
    675 /* Return the offset between two registers, one to be eliminated, and the other
    676    its replacement, at the start of a routine.  */
    677 
    678 HOST_WIDE_INT
    679 bfin_initial_elimination_offset (int from, int to)
    680 {
    681   HOST_WIDE_INT offset = 0;
    682 
    683   if (from == ARG_POINTER_REGNUM)
    684     offset = n_regs_saved_by_prologue () * 4;
    685 
    686   if (to == STACK_POINTER_REGNUM)
    687     {
    688       if (crtl->outgoing_args_size >= FIXED_STACK_AREA)
    689 	offset += crtl->outgoing_args_size;
    690       else if (crtl->outgoing_args_size)
    691 	offset += FIXED_STACK_AREA;
    692 
    693       offset += get_frame_size ();
    694     }
    695 
    696   return offset;
    697 }
    698 
    699 /* Emit code to load a constant CONSTANT into register REG; setting
    700    RTX_FRAME_RELATED_P on all insns we generate if RELATED is true.
    701    Make sure that the insns we generate need not be split.  */
    702 
    703 static void
    704 frame_related_constant_load (rtx reg, HOST_WIDE_INT constant, bool related)
    705 {
    706   rtx_insn *insn;
    707   rtx cst = GEN_INT (constant);
    708 
    709   if (constant >= -32768 && constant < 65536)
    710     insn = emit_move_insn (reg, cst);
    711   else
    712     {
    713       /* We don't call split_load_immediate here, since dwarf2out.cc can get
    714 	 confused about some of the more clever sequences it can generate.  */
    715       insn = emit_insn (gen_movsi_high (reg, cst));
    716       if (related)
    717 	RTX_FRAME_RELATED_P (insn) = 1;
    718       insn = emit_insn (gen_movsi_low (reg, reg, cst));
    719     }
    720   if (related)
    721     RTX_FRAME_RELATED_P (insn) = 1;
    722 }
    723 
    724 /* Generate efficient code to add a value to a P register.
    725    Set RTX_FRAME_RELATED_P on the generated insns if FRAME is nonzero.
    726    EPILOGUE_P is zero if this function is called for prologue,
    727    otherwise it's nonzero. And it's less than zero if this is for
    728    sibcall epilogue.  */
    729 
    730 static void
    731 add_to_reg (rtx reg, HOST_WIDE_INT value, int frame, int epilogue_p)
    732 {
    733   if (value == 0)
    734     return;
    735 
    736   /* Choose whether to use a sequence using a temporary register, or
    737      a sequence with multiple adds.  We can add a signed 7-bit value
    738      in one instruction.  */
    739   if (value > 120 || value < -120)
    740     {
    741       rtx tmpreg;
    742       rtx tmpreg2;
    743       rtx_insn *insn;
    744 
    745       tmpreg2 = NULL_RTX;
    746 
    747       /* For prologue or normal epilogue, P1 can be safely used
    748 	 as the temporary register. For sibcall epilogue, we try to find
    749 	 a call used P register, which will be restored in epilogue.
    750 	 If we cannot find such a P register, we have to use one I register
    751 	 to help us.  */
    752 
    753       if (epilogue_p >= 0)
    754 	tmpreg = gen_rtx_REG (SImode, REG_P1);
    755       else
    756 	{
    757 	  int i;
    758 	  for (i = REG_P0; i <= REG_P5; i++)
    759 	    if ((df_regs_ever_live_p (i) && ! call_used_or_fixed_reg_p (i))
    760 		|| (!TARGET_FDPIC
    761 		    && i == PIC_OFFSET_TABLE_REGNUM
    762 		    && (crtl->uses_pic_offset_table
    763 			|| (TARGET_ID_SHARED_LIBRARY
    764 			    && ! crtl->is_leaf))))
    765 	      break;
    766 	  if (i <= REG_P5)
    767 	    tmpreg = gen_rtx_REG (SImode, i);
    768 	  else
    769 	    {
    770 	      tmpreg = gen_rtx_REG (SImode, REG_P1);
    771 	      tmpreg2 = gen_rtx_REG (SImode, REG_I0);
    772 	      emit_move_insn (tmpreg2, tmpreg);
    773 	    }
    774 	}
    775 
    776       if (frame)
    777 	frame_related_constant_load (tmpreg, value, TRUE);
    778       else
    779 	insn = emit_move_insn (tmpreg, GEN_INT (value));
    780 
    781       insn = emit_insn (gen_addsi3 (reg, reg, tmpreg));
    782       if (frame)
    783 	RTX_FRAME_RELATED_P (insn) = 1;
    784 
    785       if (tmpreg2 != NULL_RTX)
    786 	emit_move_insn (tmpreg, tmpreg2);
    787     }
    788   else
    789     do
    790       {
    791 	int size = value;
    792 	rtx_insn *insn;
    793 
    794 	if (size > 60)
    795 	  size = 60;
    796 	else if (size < -60)
    797 	  /* We could use -62, but that would leave the stack unaligned, so
    798 	     it's no good.  */
    799 	  size = -60;
    800 
    801 	insn = emit_insn (gen_addsi3 (reg, reg, GEN_INT (size)));
    802 	if (frame)
    803 	  RTX_FRAME_RELATED_P (insn) = 1;
    804 	value -= size;
    805       }
    806     while (value != 0);
    807 }
    808 
    809 /* Generate a LINK insn for a frame sized FRAME_SIZE.  If this constant
    810    is too large, generate a sequence of insns that has the same effect.
    811    SPREG contains (reg:SI REG_SP).  */
    812 
    813 static void
    814 emit_link_insn (rtx spreg, HOST_WIDE_INT frame_size)
    815 {
    816   HOST_WIDE_INT link_size = frame_size;
    817   rtx_insn *insn;
    818   int i;
    819 
    820   if (link_size > 262140)
    821     link_size = 262140;
    822 
    823   /* Use a LINK insn with as big a constant as possible, then subtract
    824      any remaining size from the SP.  */
    825   insn = emit_insn (gen_link (GEN_INT (-8 - link_size)));
    826   RTX_FRAME_RELATED_P (insn) = 1;
    827 
    828   for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
    829     {
    830       rtx set = XVECEXP (PATTERN (insn), 0, i);
    831       gcc_assert (GET_CODE (set) == SET);
    832       RTX_FRAME_RELATED_P (set) = 1;
    833     }
    834 
    835   frame_size -= link_size;
    836 
    837   if (frame_size > 0)
    838     {
    839       /* Must use a call-clobbered PREG that isn't the static chain.  */
    840       rtx tmpreg = gen_rtx_REG (Pmode, REG_P1);
    841 
    842       frame_related_constant_load (tmpreg, -frame_size, TRUE);
    843       insn = emit_insn (gen_addsi3 (spreg, spreg, tmpreg));
    844       RTX_FRAME_RELATED_P (insn) = 1;
    845     }
    846 }
    847 
    848 /* Return the number of bytes we must reserve for outgoing arguments
    849    in the current function's stack frame.  */
    850 
    851 static HOST_WIDE_INT
    852 arg_area_size (void)
    853 {
    854   if (crtl->outgoing_args_size)
    855     {
    856       if (crtl->outgoing_args_size >= FIXED_STACK_AREA)
    857 	return crtl->outgoing_args_size;
    858       else
    859 	return FIXED_STACK_AREA;
    860     }
    861   return 0;
    862 }
    863 
    864 /* Save RETS and FP, and allocate a stack frame.  ALL is true if the
    865    function must save all its registers (true only for certain interrupt
    866    handlers).  */
    867 
    868 static void
    869 do_link (rtx spreg, HOST_WIDE_INT frame_size, bool all)
    870 {
    871   frame_size += arg_area_size ();
    872 
    873   if (all
    874       || stack_frame_needed_p ()
    875       || (must_save_rets_p () && must_save_fp_p ()))
    876     emit_link_insn (spreg, frame_size);
    877   else
    878     {
    879       if (must_save_rets_p ())
    880 	{
    881 	  rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
    882 					    gen_rtx_PRE_DEC (Pmode, spreg)),
    883 			       bfin_rets_rtx);
    884 	  rtx_insn *insn = emit_insn (pat);
    885 	  RTX_FRAME_RELATED_P (insn) = 1;
    886 	}
    887       if (must_save_fp_p ())
    888 	{
    889 	  rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
    890 					    gen_rtx_PRE_DEC (Pmode, spreg)),
    891 			       gen_rtx_REG (Pmode, REG_FP));
    892 	  rtx_insn *insn = emit_insn (pat);
    893 	  RTX_FRAME_RELATED_P (insn) = 1;
    894 	}
    895       add_to_reg (spreg, -frame_size, 1, 0);
    896     }
    897 }
    898 
    899 /* Like do_link, but used for epilogues to deallocate the stack frame.
    900    EPILOGUE_P is zero if this function is called for prologue,
    901    otherwise it's nonzero. And it's less than zero if this is for
    902    sibcall epilogue.  */
    903 
    904 static void
    905 do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all, int epilogue_p)
    906 {
    907   frame_size += arg_area_size ();
    908 
    909   if (stack_frame_needed_p ())
    910     emit_insn (gen_unlink ());
    911   else
    912     {
    913       rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg));
    914 
    915       add_to_reg (spreg, frame_size, 0, epilogue_p);
    916       if (all || must_save_fp_p ())
    917 	{
    918 	  rtx fpreg = gen_rtx_REG (Pmode, REG_FP);
    919 	  emit_move_insn (fpreg, postinc);
    920 	  emit_use (fpreg);
    921 	}
    922       if (all || must_save_rets_p ())
    923 	{
    924 	  emit_move_insn (bfin_rets_rtx, postinc);
    925 	  emit_use (bfin_rets_rtx);
    926 	}
    927     }
    928 }
    929 
    930 /* Generate a prologue suitable for a function of kind FKIND.  This is
    931    called for interrupt and exception handler prologues.
    932    SPREG contains (reg:SI REG_SP).  */
    933 
    934 static void
    935 expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind, bool all)
    936 {
    937   HOST_WIDE_INT frame_size = get_frame_size ();
    938   rtx predec1 = gen_rtx_PRE_DEC (SImode, spreg);
    939   rtx predec = gen_rtx_MEM (SImode, predec1);
    940   rtx_insn *insn;
    941   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
    942   tree kspisusp = lookup_attribute ("kspisusp", attrs);
    943 
    944   if (kspisusp)
    945     {
    946       insn = emit_move_insn (spreg, gen_rtx_REG (Pmode, REG_USP));
    947       RTX_FRAME_RELATED_P (insn) = 1;
    948     }
    949 
    950   /* We need space on the stack in case we need to save the argument
    951      registers.  */
    952   if (fkind == EXCPT_HANDLER)
    953     {
    954       insn = emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (-12)));
    955       RTX_FRAME_RELATED_P (insn) = 1;
    956     }
    957 
    958   /* If we're calling other functions, they won't save their call-clobbered
    959      registers, so we must save everything here.  */
    960   if (!crtl->is_leaf)
    961     all = true;
    962   expand_prologue_reg_save (spreg, all, true);
    963 
    964   if (ENABLE_WA_05000283 || ENABLE_WA_05000315)
    965     {
    966       rtx chipid = GEN_INT (trunc_int_for_mode (0xFFC00014, SImode));
    967       rtx p5reg = gen_rtx_REG (Pmode, REG_P5);
    968       emit_insn (gen_movbi (bfin_cc_rtx, const1_rtx));
    969       emit_insn (gen_movsi_high (p5reg, chipid));
    970       emit_insn (gen_movsi_low (p5reg, p5reg, chipid));
    971       emit_insn (gen_dummy_load (p5reg, bfin_cc_rtx));
    972     }
    973 
    974   if (lookup_attribute ("nesting", attrs))
    975     {
    976       rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
    977       insn = emit_move_insn (predec, srcreg);
    978       RTX_FRAME_RELATED_P (insn) = 1;
    979     }
    980 
    981   do_link (spreg, frame_size, all);
    982 
    983   if (fkind == EXCPT_HANDLER)
    984     {
    985       rtx r0reg = gen_rtx_REG (SImode, REG_R0);
    986       rtx r1reg = gen_rtx_REG (SImode, REG_R1);
    987       rtx r2reg = gen_rtx_REG (SImode, REG_R2);
    988 
    989       emit_move_insn (r0reg, gen_rtx_REG (SImode, REG_SEQSTAT));
    990       emit_insn (gen_ashrsi3 (r0reg, r0reg, GEN_INT (26)));
    991       emit_insn (gen_ashlsi3 (r0reg, r0reg, GEN_INT (26)));
    992       emit_move_insn (r1reg, spreg);
    993       emit_move_insn (r2reg, gen_rtx_REG (Pmode, REG_FP));
    994       emit_insn (gen_addsi3 (r2reg, r2reg, GEN_INT (8)));
    995     }
    996 }
    997 
    998 /* Generate an epilogue suitable for a function of kind FKIND.  This is
    999    called for interrupt and exception handler epilogues.
   1000    SPREG contains (reg:SI REG_SP).  */
   1001 
   1002 static void
   1003 expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all)
   1004 {
   1005   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
   1006   rtx postinc1 = gen_rtx_POST_INC (SImode, spreg);
   1007   rtx postinc = gen_rtx_MEM (SImode, postinc1);
   1008 
   1009   /* A slightly crude technique to stop flow from trying to delete "dead"
   1010      insns.  */
   1011   MEM_VOLATILE_P (postinc) = 1;
   1012 
   1013   do_unlink (spreg, get_frame_size (), all, 1);
   1014 
   1015   if (lookup_attribute ("nesting", attrs))
   1016     {
   1017       rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
   1018       emit_move_insn (srcreg, postinc);
   1019     }
   1020 
   1021   /* If we're calling other functions, they won't save their call-clobbered
   1022      registers, so we must save (and restore) everything here.  */
   1023   if (!crtl->is_leaf)
   1024     all = true;
   1025 
   1026   expand_epilogue_reg_restore (spreg, all, true);
   1027 
   1028   /* Deallocate any space we left on the stack in case we needed to save the
   1029      argument registers.  */
   1030   if (fkind == EXCPT_HANDLER)
   1031     emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (12)));
   1032 
   1033   emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, ret_regs[fkind])));
   1034 }
   1035 
   1036 /* Used while emitting the prologue to generate code to load the correct value
   1037    into the PIC register, which is passed in DEST.  */
   1038 
   1039 static rtx
   1040 bfin_load_pic_reg (rtx dest)
   1041 {
   1042   rtx addr;
   1043 
   1044   cgraph_node *local_info_node
   1045     = cgraph_node::local_info_node (current_function_decl);
   1046 
   1047   /* Functions local to the translation unit don't need to reload the
   1048      pic reg, since the caller always passes a usable one.  */
   1049   if (local_info_node && local_info_node->local)
   1050     return pic_offset_table_rtx;
   1051 
   1052   if (OPTION_SET_P (bfin_library_id))
   1053     addr = plus_constant (Pmode, pic_offset_table_rtx,
   1054 			   -4 - bfin_library_id * 4);
   1055   else
   1056     addr = gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
   1057 			 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
   1058 					 UNSPEC_LIBRARY_OFFSET));
   1059   emit_insn (gen_movsi (dest, gen_rtx_MEM (Pmode, addr)));
   1060   return dest;
   1061 }
   1062 
   1063 /* Generate RTL for the prologue of the current function.  */
   1064 
   1065 void
   1066 bfin_expand_prologue (void)
   1067 {
   1068   HOST_WIDE_INT frame_size = get_frame_size ();
   1069   rtx spreg = gen_rtx_REG (Pmode, REG_SP);
   1070   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
   1071   rtx pic_reg_loaded = NULL_RTX;
   1072   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
   1073   bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
   1074 
   1075   if (flag_stack_usage_info)
   1076     current_function_static_stack_size = frame_size;
   1077 
   1078   if (fkind != SUBROUTINE)
   1079     {
   1080       expand_interrupt_handler_prologue (spreg, fkind, all);
   1081       return;
   1082     }
   1083 
   1084   if (crtl->limit_stack
   1085       || (TARGET_STACK_CHECK_L1
   1086 	  && !DECL_NO_LIMIT_STACK (current_function_decl)))
   1087     {
   1088       HOST_WIDE_INT offset
   1089 	= bfin_initial_elimination_offset (ARG_POINTER_REGNUM,
   1090 					   STACK_POINTER_REGNUM);
   1091       rtx lim = crtl->limit_stack ? stack_limit_rtx : NULL_RTX;
   1092       rtx tmp = gen_rtx_REG (Pmode, REG_R3);
   1093       rtx p2reg = gen_rtx_REG (Pmode, REG_P2);
   1094 
   1095       emit_move_insn (tmp, p2reg);
   1096       if (!lim)
   1097 	{
   1098 	  emit_move_insn (p2reg, gen_int_mode (0xFFB00000, SImode));
   1099 	  emit_move_insn (p2reg, gen_rtx_MEM (Pmode, p2reg));
   1100 	  lim = p2reg;
   1101 	}
   1102       if (GET_CODE (lim) == SYMBOL_REF)
   1103 	{
   1104 	  if (TARGET_ID_SHARED_LIBRARY)
   1105 	    {
   1106 	      rtx p1reg = gen_rtx_REG (Pmode, REG_P1);
   1107 	      rtx val;
   1108 	      pic_reg_loaded = bfin_load_pic_reg (p2reg);
   1109 	      val = legitimize_pic_address (stack_limit_rtx, p1reg,
   1110 					    pic_reg_loaded);
   1111 	      emit_move_insn (p1reg, val);
   1112 	      frame_related_constant_load (p2reg, offset, FALSE);
   1113 	      emit_insn (gen_addsi3 (p2reg, p2reg, p1reg));
   1114 	      lim = p2reg;
   1115 	    }
   1116 	  else
   1117 	    {
   1118 	      rtx limit = plus_constant (Pmode, lim, offset);
   1119 	      emit_move_insn (p2reg, limit);
   1120 	      lim = p2reg;
   1121 	    }
   1122 	}
   1123       else
   1124 	{
   1125 	  if (lim != p2reg)
   1126 	    emit_move_insn (p2reg, lim);
   1127 	  add_to_reg (p2reg, offset, 0, 0);
   1128 	  lim = p2reg;
   1129 	}
   1130       emit_insn (gen_compare_lt (bfin_cc_rtx, spreg, lim));
   1131       emit_insn (gen_trapifcc ());
   1132       emit_move_insn (p2reg, tmp);
   1133     }
   1134   expand_prologue_reg_save (spreg, all, false);
   1135 
   1136   do_link (spreg, frame_size, all);
   1137 
   1138   if (TARGET_ID_SHARED_LIBRARY
   1139       && !TARGET_SEP_DATA
   1140       && (crtl->uses_pic_offset_table
   1141 	  || !crtl->is_leaf))
   1142     bfin_load_pic_reg (pic_offset_table_rtx);
   1143 }
   1144 
   1145 /* Generate RTL for the epilogue of the current function.  NEED_RETURN is zero
   1146    if this is for a sibcall.  EH_RETURN is nonzero if we're expanding an
   1147    eh_return pattern. SIBCALL_P is true if this is a sibcall epilogue,
   1148    false otherwise.  */
   1149 
   1150 void
   1151 bfin_expand_epilogue (int need_return, int eh_return, bool sibcall_p)
   1152 {
   1153   rtx spreg = gen_rtx_REG (Pmode, REG_SP);
   1154   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
   1155   int e = sibcall_p ? -1 : 1;
   1156   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
   1157   bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
   1158 
   1159   if (fkind != SUBROUTINE)
   1160     {
   1161       expand_interrupt_handler_epilogue (spreg, fkind, all);
   1162       return;
   1163     }
   1164 
   1165   do_unlink (spreg, get_frame_size (), all, e);
   1166 
   1167   expand_epilogue_reg_restore (spreg, all, false);
   1168 
   1169   /* Omit the return insn if this is for a sibcall.  */
   1170   if (! need_return)
   1171     return;
   1172 
   1173   if (eh_return)
   1174     emit_insn (gen_addsi3 (spreg, spreg, gen_rtx_REG (Pmode, REG_P2)));
   1175 
   1176   emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, REG_RETS)));
   1177 }
   1178 
   1179 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
   1181 
   1182 int
   1183 bfin_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
   1184 			   unsigned int new_reg)
   1185 {
   1186   /* Interrupt functions can only use registers that have already been
   1187      saved by the prologue, even if they would normally be
   1188      call-clobbered.  */
   1189 
   1190   if (funkind (TREE_TYPE (current_function_decl)) != SUBROUTINE
   1191       && !df_regs_ever_live_p (new_reg))
   1192     return 0;
   1193 
   1194   return 1;
   1195 }
   1196 
   1197 /* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  */
   1198 static void
   1199 bfin_extra_live_on_entry (bitmap regs)
   1200 {
   1201   if (TARGET_FDPIC)
   1202     bitmap_set_bit (regs, FDPIC_REGNO);
   1203 }
   1204 
   1205 /* Return the value of the return address for the frame COUNT steps up
   1206    from the current frame, after the prologue.
   1207    We punt for everything but the current frame by returning const0_rtx.  */
   1208 
   1209 rtx
   1210 bfin_return_addr_rtx (int count)
   1211 {
   1212   if (count != 0)
   1213     return const0_rtx;
   1214 
   1215   return get_hard_reg_initial_val (Pmode, REG_RETS);
   1216 }
   1217 
   1218 static rtx
   1219 bfin_delegitimize_address (rtx orig_x)
   1220 {
   1221   rtx x = orig_x;
   1222 
   1223   if (GET_CODE (x) != MEM)
   1224     return orig_x;
   1225 
   1226   x = XEXP (x, 0);
   1227   if (GET_CODE (x) == PLUS
   1228       && GET_CODE (XEXP (x, 1)) == UNSPEC
   1229       && XINT (XEXP (x, 1), 1) == UNSPEC_MOVE_PIC
   1230       && GET_CODE (XEXP (x, 0)) == REG
   1231       && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
   1232     return XVECEXP (XEXP (x, 1), 0, 0);
   1233 
   1234   return orig_x;
   1235 }
   1236 
   1237 /* This predicate is used to compute the length of a load/store insn.
   1238    OP is a MEM rtx, we return nonzero if its addressing mode requires a
   1239    32-bit instruction.  */
   1240 
   1241 int
   1242 effective_address_32bit_p (rtx op, machine_mode mode)
   1243 {
   1244   HOST_WIDE_INT offset;
   1245 
   1246   mode = GET_MODE (op);
   1247   op = XEXP (op, 0);
   1248 
   1249   if (GET_CODE (op) != PLUS)
   1250     {
   1251       gcc_assert (REG_P (op) || GET_CODE (op) == POST_INC
   1252 		  || GET_CODE (op) == PRE_DEC || GET_CODE (op) == POST_DEC);
   1253       return 0;
   1254     }
   1255 
   1256   if (GET_CODE (XEXP (op, 1)) == UNSPEC)
   1257     return 1;
   1258 
   1259   offset = INTVAL (XEXP (op, 1));
   1260 
   1261   /* All byte loads use a 16-bit offset.  */
   1262   if (GET_MODE_SIZE (mode) == 1)
   1263     return 1;
   1264 
   1265   if (GET_MODE_SIZE (mode) == 4)
   1266     {
   1267       /* Frame pointer relative loads can use a negative offset, all others
   1268 	 are restricted to a small positive one.  */
   1269       if (XEXP (op, 0) == frame_pointer_rtx)
   1270 	return offset < -128 || offset > 60;
   1271       return offset < 0 || offset > 60;
   1272     }
   1273 
   1274   /* Must be HImode now.  */
   1275   return offset < 0 || offset > 30;
   1276 }
   1277 
   1278 /* Returns true if X is a memory reference using an I register.  */
   1279 bool
   1280 bfin_dsp_memref_p (rtx x)
   1281 {
   1282   if (! MEM_P (x))
   1283     return false;
   1284   x = XEXP (x, 0);
   1285   if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_INC
   1286       || GET_CODE (x) == POST_DEC || GET_CODE (x) == PRE_DEC)
   1287     x = XEXP (x, 0);
   1288   return IREG_P (x);
   1289 }
   1290 
   1291 /* Return cost of the memory address ADDR.
   1292    All addressing modes are equally cheap on the Blackfin.  */
   1293 
   1294 static int
   1295 bfin_address_cost (rtx addr ATTRIBUTE_UNUSED,
   1296 		   machine_mode mode ATTRIBUTE_UNUSED,
   1297 		   addr_space_t as ATTRIBUTE_UNUSED,
   1298 		   bool speed ATTRIBUTE_UNUSED)
   1299 {
   1300   return 1;
   1301 }
   1302 
   1303 /* Subroutine of print_operand; used to print a memory reference X to FILE.  */
   1304 
   1305 void
   1306 print_address_operand (FILE *file, rtx x)
   1307 {
   1308   switch (GET_CODE (x))
   1309     {
   1310     case PLUS:
   1311       output_address (VOIDmode, XEXP (x, 0));
   1312       fprintf (file, "+");
   1313       output_address (VOIDmode, XEXP (x, 1));
   1314       break;
   1315 
   1316     case PRE_DEC:
   1317       fprintf (file, "--");
   1318       output_address (VOIDmode, XEXP (x, 0));
   1319       break;
   1320     case POST_INC:
   1321       output_address (VOIDmode, XEXP (x, 0));
   1322       fprintf (file, "++");
   1323       break;
   1324     case POST_DEC:
   1325       output_address (VOIDmode, XEXP (x, 0));
   1326       fprintf (file, "--");
   1327       break;
   1328 
   1329     default:
   1330       gcc_assert (GET_CODE (x) != MEM);
   1331       print_operand (file, x, 0);
   1332       break;
   1333     }
   1334 }
   1335 
   1336 /* Adding intp DImode support by Tony
   1337  * -- Q: (low  word)
   1338  * -- R: (high word)
   1339  */
   1340 
   1341 void
   1342 print_operand (FILE *file, rtx x, char code)
   1343 {
   1344   machine_mode mode;
   1345 
   1346   if (code == '!')
   1347     {
   1348       if (GET_MODE (current_output_insn) == SImode)
   1349 	fprintf (file, " ||");
   1350       else
   1351 	fprintf (file, ";");
   1352       return;
   1353     }
   1354 
   1355   mode = GET_MODE (x);
   1356 
   1357   switch (code)
   1358     {
   1359     case 'j':
   1360       switch (GET_CODE (x))
   1361 	{
   1362 	case EQ:
   1363 	  fprintf (file, "e");
   1364 	  break;
   1365 	case NE:
   1366 	  fprintf (file, "ne");
   1367 	  break;
   1368 	case GT:
   1369 	  fprintf (file, "g");
   1370 	  break;
   1371 	case LT:
   1372 	  fprintf (file, "l");
   1373 	  break;
   1374 	case GE:
   1375 	  fprintf (file, "ge");
   1376 	  break;
   1377 	case LE:
   1378 	  fprintf (file, "le");
   1379 	  break;
   1380 	case GTU:
   1381 	  fprintf (file, "g");
   1382 	  break;
   1383 	case LTU:
   1384 	  fprintf (file, "l");
   1385 	  break;
   1386 	case GEU:
   1387 	  fprintf (file, "ge");
   1388 	  break;
   1389 	case LEU:
   1390 	  fprintf (file, "le");
   1391 	  break;
   1392 	default:
   1393 	  output_operand_lossage ("invalid %%j value");
   1394 	}
   1395       break;
   1396 
   1397     case 'J':					 /* reverse logic */
   1398       switch (GET_CODE(x))
   1399 	{
   1400 	case EQ:
   1401 	  fprintf (file, "ne");
   1402 	  break;
   1403 	case NE:
   1404 	  fprintf (file, "e");
   1405 	  break;
   1406 	case GT:
   1407 	  fprintf (file, "le");
   1408 	  break;
   1409 	case LT:
   1410 	  fprintf (file, "ge");
   1411 	  break;
   1412 	case GE:
   1413 	  fprintf (file, "l");
   1414 	  break;
   1415 	case LE:
   1416 	  fprintf (file, "g");
   1417 	  break;
   1418 	case GTU:
   1419 	  fprintf (file, "le");
   1420 	  break;
   1421 	case LTU:
   1422 	  fprintf (file, "ge");
   1423 	  break;
   1424 	case GEU:
   1425 	  fprintf (file, "l");
   1426 	  break;
   1427 	case LEU:
   1428 	  fprintf (file, "g");
   1429 	  break;
   1430 	default:
   1431 	  output_operand_lossage ("invalid %%J value");
   1432 	}
   1433       break;
   1434 
   1435     default:
   1436       switch (GET_CODE (x))
   1437 	{
   1438 	case REG:
   1439 	  if (code == 'h')
   1440 	    {
   1441 	      if (REGNO (x) < 32)
   1442 		fprintf (file, "%s", short_reg_names[REGNO (x)]);
   1443 	      else
   1444 		output_operand_lossage ("invalid operand for code '%c'", code);
   1445 	    }
   1446 	  else if (code == 'd')
   1447 	    {
   1448 	      if (REGNO (x) < 32)
   1449 		fprintf (file, "%s", high_reg_names[REGNO (x)]);
   1450 	      else
   1451 		output_operand_lossage ("invalid operand for code '%c'", code);
   1452 	    }
   1453 	  else if (code == 'w')
   1454 	    {
   1455 	      if (REGNO (x) == REG_A0 || REGNO (x) == REG_A1)
   1456 		fprintf (file, "%s.w", reg_names[REGNO (x)]);
   1457 	      else
   1458 		output_operand_lossage ("invalid operand for code '%c'", code);
   1459 	    }
   1460 	  else if (code == 'x')
   1461 	    {
   1462 	      if (REGNO (x) == REG_A0 || REGNO (x) == REG_A1)
   1463 		fprintf (file, "%s.x", reg_names[REGNO (x)]);
   1464 	      else
   1465 		output_operand_lossage ("invalid operand for code '%c'", code);
   1466 	    }
   1467 	  else if (code == 'v')
   1468 	    {
   1469 	      if (REGNO (x) == REG_A0)
   1470 		fprintf (file, "AV0");
   1471 	      else if (REGNO (x) == REG_A1)
   1472 		fprintf (file, "AV1");
   1473 	      else
   1474 		output_operand_lossage ("invalid operand for code '%c'", code);
   1475 	    }
   1476 	  else if (code == 'D')
   1477 	    {
   1478 	      if (D_REGNO_P (REGNO (x)))
   1479 		fprintf (file, "%s", dregs_pair_names[REGNO (x)]);
   1480 	      else
   1481 		output_operand_lossage ("invalid operand for code '%c'", code);
   1482 	    }
   1483 	  else if (code == 'H')
   1484 	    {
   1485 	      if ((mode == DImode || mode == DFmode) && REG_P (x))
   1486 		fprintf (file, "%s", reg_names[REGNO (x) + 1]);
   1487 	      else
   1488 		output_operand_lossage ("invalid operand for code '%c'", code);
   1489 	    }
   1490 	  else if (code == 'T')
   1491 	    {
   1492 	      if (D_REGNO_P (REGNO (x)))
   1493 		fprintf (file, "%s", byte_reg_names[REGNO (x)]);
   1494 	      else
   1495 		output_operand_lossage ("invalid operand for code '%c'", code);
   1496 	    }
   1497 	  else
   1498 	    fprintf (file, "%s", reg_names[REGNO (x)]);
   1499 	  break;
   1500 
   1501 	case MEM:
   1502 	  fputc ('[', file);
   1503 	  x = XEXP (x,0);
   1504 	  print_address_operand (file, x);
   1505 	  fputc (']', file);
   1506 	  break;
   1507 
   1508 	case CONST_INT:
   1509 	  if (code == 'M')
   1510 	    {
   1511 	      switch (INTVAL (x))
   1512 		{
   1513 		case MACFLAG_NONE:
   1514 		  break;
   1515 		case MACFLAG_FU:
   1516 		  fputs ("(FU)", file);
   1517 		  break;
   1518 		case MACFLAG_T:
   1519 		  fputs ("(T)", file);
   1520 		  break;
   1521 		case MACFLAG_TFU:
   1522 		  fputs ("(TFU)", file);
   1523 		  break;
   1524 		case MACFLAG_W32:
   1525 		  fputs ("(W32)", file);
   1526 		  break;
   1527 		case MACFLAG_IS:
   1528 		  fputs ("(IS)", file);
   1529 		  break;
   1530 		case MACFLAG_IU:
   1531 		  fputs ("(IU)", file);
   1532 		  break;
   1533 		case MACFLAG_IH:
   1534 		  fputs ("(IH)", file);
   1535 		  break;
   1536 		case MACFLAG_M:
   1537 		  fputs ("(M)", file);
   1538 		  break;
   1539 		case MACFLAG_IS_M:
   1540 		  fputs ("(IS,M)", file);
   1541 		  break;
   1542 		case MACFLAG_ISS2:
   1543 		  fputs ("(ISS2)", file);
   1544 		  break;
   1545 		case MACFLAG_S2RND:
   1546 		  fputs ("(S2RND)", file);
   1547 		  break;
   1548 		default:
   1549 		  gcc_unreachable ();
   1550 		}
   1551 	      break;
   1552 	    }
   1553 	  else if (code == 'b')
   1554 	    {
   1555 	      if (INTVAL (x) == 0)
   1556 		fputs ("+=", file);
   1557 	      else if (INTVAL (x) == 1)
   1558 		fputs ("-=", file);
   1559 	      else
   1560 		gcc_unreachable ();
   1561 	      break;
   1562 	    }
   1563 	  /* Moves to half registers with d or h modifiers always use unsigned
   1564 	     constants.  */
   1565 	  else if (code == 'd')
   1566 	    x = GEN_INT ((INTVAL (x) >> 16) & 0xffff);
   1567 	  else if (code == 'h')
   1568 	    x = GEN_INT (INTVAL (x) & 0xffff);
   1569 	  else if (code == 'N')
   1570 	    x = GEN_INT (-INTVAL (x));
   1571 	  else if (code == 'X')
   1572 	    x = GEN_INT (exact_log2 (0xffffffff & INTVAL (x)));
   1573 	  else if (code == 'Y')
   1574 	    x = GEN_INT (exact_log2 (0xffffffff & ~INTVAL (x)));
   1575 	  else if (code == 'Z')
   1576 	    /* Used for LINK insns.  */
   1577 	    x = GEN_INT (-8 - INTVAL (x));
   1578 
   1579 	  /* fall through */
   1580 
   1581 	case SYMBOL_REF:
   1582 	  output_addr_const (file, x);
   1583 	  break;
   1584 
   1585 	case CONST_DOUBLE:
   1586 	  output_operand_lossage ("invalid const_double operand");
   1587 	  break;
   1588 
   1589 	case UNSPEC:
   1590 	  switch (XINT (x, 1))
   1591 	    {
   1592 	    case UNSPEC_MOVE_PIC:
   1593 	      output_addr_const (file, XVECEXP (x, 0, 0));
   1594 	      fprintf (file, "@GOT");
   1595 	      break;
   1596 
   1597 	    case UNSPEC_MOVE_FDPIC:
   1598 	      output_addr_const (file, XVECEXP (x, 0, 0));
   1599 	      fprintf (file, "@GOT17M4");
   1600 	      break;
   1601 
   1602 	    case UNSPEC_FUNCDESC_GOT17M4:
   1603 	      output_addr_const (file, XVECEXP (x, 0, 0));
   1604 	      fprintf (file, "@FUNCDESC_GOT17M4");
   1605 	      break;
   1606 
   1607 	    case UNSPEC_LIBRARY_OFFSET:
   1608 	      fprintf (file, "_current_shared_library_p5_offset_");
   1609 	      break;
   1610 
   1611 	    default:
   1612 	      gcc_unreachable ();
   1613 	    }
   1614 	  break;
   1615 
   1616 	default:
   1617 	  output_addr_const (file, x);
   1618 	}
   1619     }
   1620 }
   1621 
   1622 /* Argument support functions.  */
   1624 
   1625 /* Initialize a variable CUM of type CUMULATIVE_ARGS
   1626    for a call to a function whose data type is FNTYPE.
   1627    For a library call, FNTYPE is 0.
   1628    VDSP C Compiler manual, our ABI says that
   1629    first 3 words of arguments will use R0, R1 and R2.
   1630 */
   1631 
   1632 void
   1633 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
   1634 		      rtx libname ATTRIBUTE_UNUSED)
   1635 {
   1636   static CUMULATIVE_ARGS zero_cum;
   1637 
   1638   *cum = zero_cum;
   1639 
   1640   /* Set up the number of registers to use for passing arguments.  */
   1641 
   1642   cum->nregs = max_arg_registers;
   1643   cum->arg_regs = arg_regs;
   1644 
   1645   cum->call_cookie = CALL_NORMAL;
   1646   /* Check for a longcall attribute.  */
   1647   if (fntype && lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
   1648     cum->call_cookie |= CALL_SHORT;
   1649   else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
   1650     cum->call_cookie |= CALL_LONG;
   1651 
   1652   return;
   1653 }
   1654 
   1655 /* Update the data in CUM to advance over argument ARG.  */
   1656 
   1657 static void
   1658 bfin_function_arg_advance (cumulative_args_t cum_v,
   1659 			   const function_arg_info &arg)
   1660 {
   1661   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   1662   int count, bytes, words;
   1663 
   1664   bytes = arg.promoted_size_in_bytes ();
   1665   words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
   1666 
   1667   cum->words += words;
   1668   cum->nregs -= words;
   1669 
   1670   if (cum->nregs <= 0)
   1671     {
   1672       cum->nregs = 0;
   1673       cum->arg_regs = NULL;
   1674     }
   1675   else
   1676     {
   1677       for (count = 1; count <= words; count++)
   1678         cum->arg_regs++;
   1679     }
   1680 
   1681   return;
   1682 }
   1683 
   1684 /* Define where to put the arguments to a function.
   1685    Value is zero to push the argument on the stack,
   1686    or a hard register in which to store the argument.
   1687 
   1688    CUM is a variable of type CUMULATIVE_ARGS which gives info about
   1689     the preceding args and about the function being called.
   1690    ARG is a description of the argument.  */
   1691 
   1692 static rtx
   1693 bfin_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
   1694 {
   1695   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   1696   int bytes = arg.promoted_size_in_bytes ();
   1697 
   1698   if (arg.end_marker_p ())
   1699     /* Compute operand 2 of the call insn.  */
   1700     return GEN_INT (cum->call_cookie);
   1701 
   1702   if (bytes == -1)
   1703     return NULL_RTX;
   1704 
   1705   if (cum->nregs)
   1706     return gen_rtx_REG (arg.mode, *(cum->arg_regs));
   1707 
   1708   return NULL_RTX;
   1709 }
   1710 
   1711 /* For an arg passed partly in registers and partly in memory,
   1712    this is the number of bytes passed in registers.
   1713    For args passed entirely in registers or entirely in memory, zero.
   1714 
   1715    Refer VDSP C Compiler manual, our ABI.
   1716    First 3 words are in registers. So, if an argument is larger
   1717    than the registers available, it will span the register and
   1718    stack.   */
   1719 
   1720 static int
   1721 bfin_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
   1722 {
   1723   int bytes = arg.promoted_size_in_bytes ();
   1724   int bytes_left = get_cumulative_args (cum)->nregs * UNITS_PER_WORD;
   1725 
   1726   if (bytes == -1)
   1727     return 0;
   1728 
   1729   if (bytes_left == 0)
   1730     return 0;
   1731   if (bytes > bytes_left)
   1732     return bytes_left;
   1733   return 0;
   1734 }
   1735 
   1736 /* Variable sized types are passed by reference.  */
   1737 
   1738 static bool
   1739 bfin_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
   1740 {
   1741   return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST;
   1742 }
   1743 
   1744 /* Decide whether a type should be returned in memory (true)
   1745    or in a register (false).  This is called by the macro
   1746    TARGET_RETURN_IN_MEMORY.  */
   1747 
   1748 static bool
   1749 bfin_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
   1750 {
   1751   int size = int_size_in_bytes (type);
   1752   return size > 2 * UNITS_PER_WORD || size == -1;
   1753 }
   1754 
   1755 /* Register in which address to store a structure value
   1756    is passed to a function.  */
   1757 static rtx
   1758 bfin_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
   1759 		      int incoming ATTRIBUTE_UNUSED)
   1760 {
   1761   return gen_rtx_REG (Pmode, REG_P0);
   1762 }
   1763 
   1764 /* Return true when register may be used to pass function parameters.  */
   1765 
   1766 bool
   1767 function_arg_regno_p (int n)
   1768 {
   1769   int i;
   1770   for (i = 0; arg_regs[i] != -1; i++)
   1771     if (n == arg_regs[i])
   1772       return true;
   1773   return false;
   1774 }
   1775 
   1776 /* Returns 1 if OP contains a symbol reference */
   1777 
   1778 int
   1779 symbolic_reference_mentioned_p (rtx op)
   1780 {
   1781   const char *fmt;
   1782   int i;
   1783 
   1784   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
   1785     return 1;
   1786 
   1787   fmt = GET_RTX_FORMAT (GET_CODE (op));
   1788   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
   1789     {
   1790       if (fmt[i] == 'E')
   1791 	{
   1792 	  int j;
   1793 
   1794 	  for (j = XVECLEN (op, i) - 1; j >= 0; j--)
   1795 	    if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
   1796 	      return 1;
   1797 	}
   1798 
   1799       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
   1800 	return 1;
   1801     }
   1802 
   1803   return 0;
   1804 }
   1805 
   1806 /* Decide whether we can make a sibling call to a function.  DECL is the
   1807    declaration of the function being targeted by the call and EXP is the
   1808    CALL_EXPR representing the call.  */
   1809 
   1810 static bool
   1811 bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
   1812 			      tree exp ATTRIBUTE_UNUSED)
   1813 {
   1814   cgraph_node *this_func, *called_func;
   1815   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
   1816   if (fkind != SUBROUTINE)
   1817     return false;
   1818   if (!TARGET_ID_SHARED_LIBRARY || TARGET_SEP_DATA)
   1819     return true;
   1820 
   1821   /* When compiling for ID shared libraries, can't sibcall a local function
   1822      from a non-local function, because the local function thinks it does
   1823      not need to reload P5 in the prologue, but the sibcall wil pop P5 in the
   1824      sibcall epilogue, and we end up with the wrong value in P5.  */
   1825 
   1826   if (!decl)
   1827     /* Not enough information.  */
   1828     return false;
   1829 
   1830   this_func = cgraph_node::local_info_node (current_function_decl);
   1831   called_func = cgraph_node::local_info_node (decl);
   1832   if (!called_func)
   1833     return false;
   1834   return !called_func->local || this_func->local;
   1835 }
   1836 
   1837 /* Write a template for a trampoline to F.  */
   1839 
   1840 static void
   1841 bfin_asm_trampoline_template (FILE *f)
   1842 {
   1843   if (TARGET_FDPIC)
   1844     {
   1845       fprintf (f, "\t.dd\t0x00000000\n");	/* 0 */
   1846       fprintf (f, "\t.dd\t0x00000000\n");	/* 0 */
   1847       fprintf (f, "\t.dd\t0x0000e109\n");	/* p1.l = fn low */
   1848       fprintf (f, "\t.dd\t0x0000e149\n");	/* p1.h = fn high */
   1849       fprintf (f, "\t.dd\t0x0000e10a\n");	/* p2.l = sc low */
   1850       fprintf (f, "\t.dd\t0x0000e14a\n");	/* p2.h = sc high */
   1851       fprintf (f, "\t.dw\t0xac4b\n");		/* p3 = [p1 + 4] */
   1852       fprintf (f, "\t.dw\t0x9149\n");		/* p1 = [p1] */
   1853       fprintf (f, "\t.dw\t0x0051\n");		/* jump (p1)*/
   1854     }
   1855   else
   1856     {
   1857       fprintf (f, "\t.dd\t0x0000e109\n");	/* p1.l = fn low */
   1858       fprintf (f, "\t.dd\t0x0000e149\n");	/* p1.h = fn high */
   1859       fprintf (f, "\t.dd\t0x0000e10a\n");	/* p2.l = sc low */
   1860       fprintf (f, "\t.dd\t0x0000e14a\n");	/* p2.h = sc high */
   1861       fprintf (f, "\t.dw\t0x0051\n");		/* jump (p1)*/
   1862     }
   1863 }
   1864 
   1865 /* Emit RTL insns to initialize the variable parts of a trampoline at
   1866    M_TRAMP. FNDECL is the target function.  CHAIN_VALUE is an RTX for
   1867    the static chain value for the function.  */
   1868 
   1869 static void
   1870 bfin_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   1871 {
   1872   rtx t1 = copy_to_reg (XEXP (DECL_RTL (fndecl), 0));
   1873   rtx t2 = copy_to_reg (chain_value);
   1874   rtx mem;
   1875   int i = 0;
   1876 
   1877   emit_block_move (m_tramp, assemble_trampoline_template (),
   1878 		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
   1879 
   1880   if (TARGET_FDPIC)
   1881     {
   1882       rtx a = force_reg (Pmode, plus_constant (Pmode, XEXP (m_tramp, 0), 8));
   1883       mem = adjust_address (m_tramp, Pmode, 0);
   1884       emit_move_insn (mem, a);
   1885       i = 8;
   1886     }
   1887 
   1888   mem = adjust_address (m_tramp, HImode, i + 2);
   1889   emit_move_insn (mem, gen_lowpart (HImode, t1));
   1890   emit_insn (gen_ashrsi3 (t1, t1, GEN_INT (16)));
   1891   mem = adjust_address (m_tramp, HImode, i + 6);
   1892   emit_move_insn (mem, gen_lowpart (HImode, t1));
   1893 
   1894   mem = adjust_address (m_tramp, HImode, i + 10);
   1895   emit_move_insn (mem, gen_lowpart (HImode, t2));
   1896   emit_insn (gen_ashrsi3 (t2, t2, GEN_INT (16)));
   1897   mem = adjust_address (m_tramp, HImode, i + 14);
   1898   emit_move_insn (mem, gen_lowpart (HImode, t2));
   1899 }
   1900 
   1901 /* Emit insns to move operands[1] into operands[0].  */
   1902 
   1903 void
   1904 emit_pic_move (rtx *operands, machine_mode mode ATTRIBUTE_UNUSED)
   1905 {
   1906   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
   1907 
   1908   gcc_assert (!TARGET_FDPIC || !(reload_in_progress || reload_completed));
   1909   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
   1910     operands[1] = force_reg (SImode, operands[1]);
   1911   else
   1912     operands[1] = legitimize_pic_address (operands[1], temp,
   1913 					  TARGET_FDPIC ? OUR_FDPIC_REG
   1914 					  : pic_offset_table_rtx);
   1915 }
   1916 
   1917 /* Expand a move operation in mode MODE.  The operands are in OPERANDS.
   1918    Returns true if no further code must be generated, false if the caller
   1919    should generate an insn to move OPERANDS[1] to OPERANDS[0].  */
   1920 
   1921 bool
   1922 expand_move (rtx *operands, machine_mode mode)
   1923 {
   1924   rtx op = operands[1];
   1925   if ((TARGET_ID_SHARED_LIBRARY || TARGET_FDPIC)
   1926       && SYMBOLIC_CONST (op))
   1927     emit_pic_move (operands, mode);
   1928   else if (mode == SImode && GET_CODE (op) == CONST
   1929 	   && GET_CODE (XEXP (op, 0)) == PLUS
   1930 	   && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
   1931 	   && !targetm.legitimate_constant_p (mode, op))
   1932     {
   1933       rtx dest = operands[0];
   1934       rtx op0, op1;
   1935       gcc_assert (!reload_in_progress && !reload_completed);
   1936       op = XEXP (op, 0);
   1937       op0 = force_reg (mode, XEXP (op, 0));
   1938       op1 = XEXP (op, 1);
   1939       if (!insn_data[CODE_FOR_addsi3].operand[2].predicate (op1, mode))
   1940 	op1 = force_reg (mode, op1);
   1941       if (GET_CODE (dest) == MEM)
   1942 	dest = gen_reg_rtx (mode);
   1943       emit_insn (gen_addsi3 (dest, op0, op1));
   1944       if (dest == operands[0])
   1945 	return true;
   1946       operands[1] = dest;
   1947     }
   1948   /* Don't generate memory->memory or constant->memory moves, go through a
   1949      register */
   1950   else if ((reload_in_progress | reload_completed) == 0
   1951 	   && GET_CODE (operands[0]) == MEM
   1952     	   && GET_CODE (operands[1]) != REG)
   1953     operands[1] = force_reg (mode, operands[1]);
   1954   return false;
   1955 }
   1956 
   1957 /* Split one or more DImode RTL references into pairs of SImode
   1959    references.  The RTL can be REG, offsettable MEM, integer constant, or
   1960    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
   1961    split and "num" is its length.  lo_half and hi_half are output arrays
   1962    that parallel "operands".  */
   1963 
   1964 void
   1965 split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
   1966 {
   1967   while (num--)
   1968     {
   1969       rtx op = operands[num];
   1970 
   1971       /* simplify_subreg refuse to split volatile memory addresses,
   1972          but we still have to handle it.  */
   1973       if (GET_CODE (op) == MEM)
   1974 	{
   1975 	  lo_half[num] = adjust_address (op, SImode, 0);
   1976 	  hi_half[num] = adjust_address (op, SImode, 4);
   1977 	}
   1978       else
   1979 	{
   1980 	  lo_half[num] = simplify_gen_subreg (SImode, op,
   1981 					      GET_MODE (op) == VOIDmode
   1982 					      ? DImode : GET_MODE (op), 0);
   1983 	  hi_half[num] = simplify_gen_subreg (SImode, op,
   1984 					      GET_MODE (op) == VOIDmode
   1985 					      ? DImode : GET_MODE (op), 4);
   1986 	}
   1987     }
   1988 }
   1989 
   1990 bool
   1992 bfin_longcall_p (rtx op, int call_cookie)
   1993 {
   1994   gcc_assert (GET_CODE (op) == SYMBOL_REF);
   1995   if (SYMBOL_REF_WEAK (op))
   1996     return 1;
   1997   if (call_cookie & CALL_SHORT)
   1998     return 0;
   1999   if (call_cookie & CALL_LONG)
   2000     return 1;
   2001   if (TARGET_LONG_CALLS)
   2002     return 1;
   2003   return 0;
   2004 }
   2005 
   2006 /* Expand a call instruction.  FNADDR is the call target, RETVAL the return value.
   2007    COOKIE is a CONST_INT holding the call_cookie prepared init_cumulative_args.
   2008    SIBCALL is nonzero if this is a sibling call.  */
   2009 
   2010 void
   2011 bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall)
   2012 {
   2013   rtx use = NULL, call;
   2014   rtx callee = XEXP (fnaddr, 0);
   2015   int nelts = 3;
   2016   rtx pat;
   2017   rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REGNO);
   2018   rtx retsreg = gen_rtx_REG (Pmode, REG_RETS);
   2019   int n;
   2020 
   2021   /* In an untyped call, we can get NULL for operand 2.  */
   2022   if (cookie == NULL_RTX)
   2023     cookie = const0_rtx;
   2024 
   2025   /* Static functions and indirect calls don't need the pic register.  */
   2026   if (!TARGET_FDPIC && flag_pic
   2027       && GET_CODE (callee) == SYMBOL_REF
   2028       && !SYMBOL_REF_LOCAL_P (callee))
   2029     use_reg (&use, pic_offset_table_rtx);
   2030 
   2031   if (TARGET_FDPIC)
   2032     {
   2033       int caller_in_sram, callee_in_sram;
   2034 
   2035       /* 0 is not in sram, 1 is in L1 sram, 2 is in L2 sram.  */
   2036       caller_in_sram = callee_in_sram = 0;
   2037 
   2038       if (lookup_attribute ("l1_text",
   2039 			    DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE)
   2040 	caller_in_sram = 1;
   2041       else if (lookup_attribute ("l2",
   2042 				 DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE)
   2043 	caller_in_sram = 2;
   2044 
   2045       if (GET_CODE (callee) == SYMBOL_REF
   2046 	  && SYMBOL_REF_DECL (callee) && DECL_P (SYMBOL_REF_DECL (callee)))
   2047 	{
   2048 	  if (lookup_attribute
   2049 	      ("l1_text",
   2050 	       DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE)
   2051 	    callee_in_sram = 1;
   2052 	  else if (lookup_attribute
   2053 		   ("l2",
   2054 		    DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE)
   2055 	    callee_in_sram = 2;
   2056 	}
   2057 
   2058       if (GET_CODE (callee) != SYMBOL_REF
   2059 	  || bfin_longcall_p (callee, INTVAL (cookie))
   2060 	  || (GET_CODE (callee) == SYMBOL_REF
   2061 	      && !SYMBOL_REF_LOCAL_P (callee)
   2062 	      && TARGET_INLINE_PLT)
   2063 	  || caller_in_sram != callee_in_sram
   2064 	  || (caller_in_sram && callee_in_sram
   2065 	      && (GET_CODE (callee) != SYMBOL_REF
   2066 		  || !SYMBOL_REF_LOCAL_P (callee))))
   2067 	{
   2068 	  rtx addr = callee;
   2069 	  if (! address_operand (addr, Pmode))
   2070 	    addr = force_reg (Pmode, addr);
   2071 
   2072 	  fnaddr = gen_reg_rtx (SImode);
   2073 	  emit_insn (gen_load_funcdescsi (fnaddr, addr));
   2074 	  fnaddr = gen_rtx_MEM (Pmode, fnaddr);
   2075 
   2076 	  picreg = gen_reg_rtx (SImode);
   2077 	  emit_insn (gen_load_funcdescsi (picreg,
   2078 					  plus_constant (Pmode, addr, 4)));
   2079 	}
   2080 
   2081       nelts++;
   2082     }
   2083   else if ((!register_no_elim_operand (callee, Pmode)
   2084 	    && GET_CODE (callee) != SYMBOL_REF)
   2085 	   || (GET_CODE (callee) == SYMBOL_REF
   2086 	       && ((TARGET_ID_SHARED_LIBRARY && !TARGET_LEAF_ID_SHARED_LIBRARY)
   2087 		   || bfin_longcall_p (callee, INTVAL (cookie)))))
   2088     {
   2089       callee = copy_to_mode_reg (Pmode, callee);
   2090       fnaddr = gen_rtx_MEM (Pmode, callee);
   2091     }
   2092   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
   2093 
   2094   if (retval)
   2095     call = gen_rtx_SET (retval, call);
   2096 
   2097   pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nelts));
   2098   n = 0;
   2099   XVECEXP (pat, 0, n++) = call;
   2100   if (TARGET_FDPIC)
   2101     XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, picreg);
   2102   XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, cookie);
   2103   if (sibcall)
   2104     XVECEXP (pat, 0, n++) = ret_rtx;
   2105   else
   2106     XVECEXP (pat, 0, n++) = gen_rtx_CLOBBER (VOIDmode, retsreg);
   2107   call = emit_call_insn (pat);
   2108   if (use)
   2109     CALL_INSN_FUNCTION_USAGE (call) = use;
   2110 }
   2111 
   2112 /* Implement TARGET_HARD_REGNO_NREGS.  */
   2114 
   2115 static unsigned int
   2116 bfin_hard_regno_nregs (unsigned int regno, machine_mode mode)
   2117 {
   2118   if (mode == PDImode && (regno == REG_A0 || regno == REG_A1))
   2119     return 1;
   2120   if (mode == V2PDImode && (regno == REG_A0 || regno == REG_A1))
   2121     return 2;
   2122   return CLASS_MAX_NREGS (GENERAL_REGS, mode);
   2123 }
   2124 
   2125 /* Implement TARGET_HARD_REGNO_MODE_OK.
   2126 
   2127    Do not allow to store a value in REG_CC for any mode.
   2128    Do not allow to store value in pregs if mode is not SI.  */
   2129 static bool
   2130 bfin_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   2131 {
   2132   /* Allow only dregs to store value of mode HI or QI */
   2133   enum reg_class rclass = REGNO_REG_CLASS (regno);
   2134 
   2135   if (mode == CCmode)
   2136     return false;
   2137 
   2138   if (mode == V2HImode)
   2139     return D_REGNO_P (regno);
   2140   if (rclass == CCREGS)
   2141     return mode == BImode;
   2142   if (mode == PDImode || mode == V2PDImode)
   2143     return regno == REG_A0 || regno == REG_A1;
   2144 
   2145   /* Allow all normal 32-bit regs, except REG_M3, in case regclass ever comes
   2146      up with a bad register class (such as ALL_REGS) for DImode.  */
   2147   if (mode == DImode)
   2148     return regno < REG_M3;
   2149 
   2150   if (mode == SImode
   2151       && TEST_HARD_REG_BIT (reg_class_contents[PROLOGUE_REGS], regno))
   2152     return true;
   2153 
   2154   return TEST_HARD_REG_BIT (reg_class_contents[MOST_REGS], regno);
   2155 }
   2156 
   2157 /* Implement TARGET_MODES_TIEABLE_P.  */
   2158 
   2159 static bool
   2160 bfin_modes_tieable_p (machine_mode mode1, machine_mode mode2)
   2161 {
   2162   return (mode1 == mode2
   2163 	  || ((GET_MODE_CLASS (mode1) == MODE_INT
   2164 	       || GET_MODE_CLASS (mode1) == MODE_FLOAT)
   2165 	      && (GET_MODE_CLASS (mode2) == MODE_INT
   2166 		  || GET_MODE_CLASS (mode2) == MODE_FLOAT)
   2167 	      && mode1 != BImode && mode2 != BImode
   2168 	      && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
   2169 	      && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD));
   2170 }
   2171 
   2172 /* Implements target hook vector_mode_supported_p.  */
   2173 
   2174 static bool
   2175 bfin_vector_mode_supported_p (machine_mode mode)
   2176 {
   2177   return mode == V2HImode;
   2178 }
   2179 
   2180 /* Worker function for TARGET_REGISTER_MOVE_COST.  */
   2181 
   2182 static int
   2183 bfin_register_move_cost (machine_mode mode,
   2184 			 reg_class_t class1, reg_class_t class2)
   2185 {
   2186   /* These need secondary reloads, so they're more expensive.  */
   2187   if ((class1 == CCREGS && !reg_class_subset_p (class2, DREGS))
   2188       || (class2 == CCREGS && !reg_class_subset_p (class1, DREGS)))
   2189     return 4;
   2190 
   2191   /* If optimizing for size, always prefer reg-reg over reg-memory moves.  */
   2192   if (optimize_size)
   2193     return 2;
   2194 
   2195   if (GET_MODE_CLASS (mode) == MODE_INT)
   2196     {
   2197       /* Discourage trying to use the accumulators.  */
   2198       if (TEST_HARD_REG_BIT (reg_class_contents[class1], REG_A0)
   2199 	  || TEST_HARD_REG_BIT (reg_class_contents[class1], REG_A1)
   2200 	  || TEST_HARD_REG_BIT (reg_class_contents[class2], REG_A0)
   2201 	  || TEST_HARD_REG_BIT (reg_class_contents[class2], REG_A1))
   2202 	return 20;
   2203     }
   2204   return 2;
   2205 }
   2206 
   2207 /* Worker function for TARGET_MEMORY_MOVE_COST.
   2208 
   2209    ??? In theory L1 memory has single-cycle latency.  We should add a switch
   2210    that tells the compiler whether we expect to use only L1 memory for the
   2211    program; it'll make the costs more accurate.  */
   2212 
   2213 static int
   2214 bfin_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
   2215 		       reg_class_t rclass,
   2216 		       bool in ATTRIBUTE_UNUSED)
   2217 {
   2218   /* Make memory accesses slightly more expensive than any register-register
   2219      move.  Also, penalize non-DP registers, since they need secondary
   2220      reloads to load and store.  */
   2221   if (! reg_class_subset_p (rclass, DPREGS))
   2222     return 10;
   2223 
   2224   return 8;
   2225 }
   2226 
   2227 /* Inform reload about cases where moving X with a mode MODE to a register in
   2228    RCLASS requires an extra scratch register.  Return the class needed for the
   2229    scratch register.  */
   2230 
   2231 static reg_class_t
   2232 bfin_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
   2233 		       machine_mode mode, secondary_reload_info *sri)
   2234 {
   2235   /* If we have HImode or QImode, we can only use DREGS as secondary registers;
   2236      in most other cases we can also use PREGS.  */
   2237   enum reg_class default_class = GET_MODE_SIZE (mode) >= 4 ? DPREGS : DREGS;
   2238   enum reg_class x_class = NO_REGS;
   2239   enum rtx_code code = GET_CODE (x);
   2240   enum reg_class rclass = (enum reg_class) rclass_i;
   2241 
   2242   if (code == SUBREG)
   2243     x = SUBREG_REG (x), code = GET_CODE (x);
   2244   if (REG_P (x))
   2245     {
   2246       int regno = REGNO (x);
   2247       if (regno >= FIRST_PSEUDO_REGISTER)
   2248 	regno = reg_renumber[regno];
   2249 
   2250       if (regno == -1)
   2251 	code = MEM;
   2252       else
   2253 	x_class = REGNO_REG_CLASS (regno);
   2254     }
   2255 
   2256   /* We can be asked to reload (plus (FP) (large_constant)) into a DREG.
   2257      This happens as a side effect of register elimination, and we need
   2258      a scratch register to do it.  */
   2259   if (fp_plus_const_operand (x, mode))
   2260     {
   2261       rtx op2 = XEXP (x, 1);
   2262       int large_constant_p = ! satisfies_constraint_Ks7 (op2);
   2263 
   2264       if (rclass == PREGS || rclass == PREGS_CLOBBERED)
   2265 	return NO_REGS;
   2266       /* If destination is a DREG, we can do this without a scratch register
   2267 	 if the constant is valid for an add instruction.  */
   2268       if ((rclass == DREGS || rclass == DPREGS)
   2269 	  && ! large_constant_p)
   2270 	return NO_REGS;
   2271       /* Reloading to anything other than a DREG?  Use a PREG scratch
   2272 	 register.  */
   2273       sri->icode = CODE_FOR_reload_insi;
   2274       return NO_REGS;
   2275     }
   2276 
   2277   /* Data can usually be moved freely between registers of most classes.
   2278      AREGS are an exception; they can only move to or from another register
   2279      in AREGS or one in DREGS.  They can also be assigned the constant 0.  */
   2280   if (x_class == AREGS || x_class == EVEN_AREGS || x_class == ODD_AREGS)
   2281     return (rclass == DREGS || rclass == AREGS || rclass == EVEN_AREGS
   2282 	    || rclass == ODD_AREGS
   2283 	    ? NO_REGS : DREGS);
   2284 
   2285   if (rclass == AREGS || rclass == EVEN_AREGS || rclass == ODD_AREGS)
   2286     {
   2287       if (code == MEM)
   2288 	{
   2289 	  sri->icode = in_p ? CODE_FOR_reload_inpdi : CODE_FOR_reload_outpdi;
   2290 	  return NO_REGS;
   2291 	}
   2292 
   2293       if (x != const0_rtx && x_class != DREGS)
   2294 	{
   2295 	  return DREGS;
   2296 	}
   2297       else
   2298 	return NO_REGS;
   2299     }
   2300 
   2301   /* CCREGS can only be moved from/to DREGS.  */
   2302   if (rclass == CCREGS && x_class != DREGS)
   2303     return DREGS;
   2304   if (x_class == CCREGS && rclass != DREGS)
   2305     return DREGS;
   2306 
   2307   /* All registers other than AREGS can load arbitrary constants.  The only
   2308      case that remains is MEM.  */
   2309   if (code == MEM)
   2310     if (! reg_class_subset_p (rclass, default_class))
   2311       return default_class;
   2312 
   2313   return NO_REGS;
   2314 }
   2315 
   2316 /* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
   2317 
   2318 static bool
   2319 bfin_class_likely_spilled_p (reg_class_t rclass)
   2320 {
   2321   switch (rclass)
   2322     {
   2323       case PREGS_CLOBBERED:
   2324       case PROLOGUE_REGS:
   2325       case P0REGS:
   2326       case D0REGS:
   2327       case D1REGS:
   2328       case D2REGS:
   2329       case CCREGS:
   2330         return true;
   2331 
   2332       default:
   2333         break;
   2334     }
   2335 
   2336   return false;
   2337 }
   2338 
   2339 static struct machine_function *
   2341 bfin_init_machine_status (void)
   2342 {
   2343   return ggc_cleared_alloc<machine_function> ();
   2344 }
   2345 
   2346 /* Implement the TARGET_OPTION_OVERRIDE hook.  */
   2347 
   2348 static void
   2349 bfin_option_override (void)
   2350 {
   2351   /* If processor type is not specified, enable all workarounds.  */
   2352   if (bfin_cpu_type == BFIN_CPU_UNKNOWN)
   2353     {
   2354       int i;
   2355 
   2356       for (i = 0; bfin_cpus[i].name != NULL; i++)
   2357 	bfin_workarounds |= bfin_cpus[i].workarounds;
   2358 
   2359       bfin_si_revision = 0xffff;
   2360     }
   2361 
   2362   if (bfin_csync_anomaly == 1)
   2363     bfin_workarounds |= WA_SPECULATIVE_SYNCS;
   2364   else if (bfin_csync_anomaly == 0)
   2365     bfin_workarounds &= ~WA_SPECULATIVE_SYNCS;
   2366 
   2367   if (bfin_specld_anomaly == 1)
   2368     bfin_workarounds |= WA_SPECULATIVE_LOADS;
   2369   else if (bfin_specld_anomaly == 0)
   2370     bfin_workarounds &= ~WA_SPECULATIVE_LOADS;
   2371 
   2372   if (TARGET_OMIT_LEAF_FRAME_POINTER)
   2373     flag_omit_frame_pointer = 1;
   2374 
   2375 #ifdef SUBTARGET_FDPIC_NOT_SUPPORTED
   2376   if (TARGET_FDPIC)
   2377     error ("%<-mfdpic%> is not supported, please use a bfin-linux-uclibc "
   2378 	   "target");
   2379 #endif
   2380 
   2381   /* Library identification */
   2382   if (OPTION_SET_P (bfin_library_id) && ! TARGET_ID_SHARED_LIBRARY)
   2383     error ("%<-mshared-library-id=%> specified without "
   2384 	   "%<-mid-shared-library%>");
   2385 
   2386   if (stack_limit_rtx && TARGET_FDPIC)
   2387     {
   2388       warning (0, "%<-fstack-limit-%> options are ignored with %<-mfdpic%>; "
   2389 	       "use %<-mstack-check-l1%>");
   2390       stack_limit_rtx = NULL_RTX;
   2391     }
   2392 
   2393   if (stack_limit_rtx && TARGET_STACK_CHECK_L1)
   2394     error ("cannot use multiple stack checking methods together");
   2395 
   2396   if (TARGET_ID_SHARED_LIBRARY && TARGET_FDPIC)
   2397     error ("ID shared libraries and FD-PIC mode cannot be used together");
   2398 
   2399   /* Don't allow the user to specify -mid-shared-library and -msep-data
   2400      together, as it makes little sense from a user's point of view...  */
   2401   if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
   2402     error ("cannot specify both %<-msep-data%> and %<-mid-shared-library%>");
   2403   /* ... internally, however, it's nearly the same.  */
   2404   if (TARGET_SEP_DATA)
   2405     target_flags |= MASK_ID_SHARED_LIBRARY | MASK_LEAF_ID_SHARED_LIBRARY;
   2406 
   2407   if (TARGET_ID_SHARED_LIBRARY && flag_pic == 0)
   2408     flag_pic = 1;
   2409 
   2410   /* There is no single unaligned SI op for PIC code.  Sometimes we
   2411      need to use ".4byte" and sometimes we need to use ".picptr".
   2412      See bfin_assemble_integer for details.  */
   2413   if (TARGET_FDPIC)
   2414     targetm.asm_out.unaligned_op.si = 0;
   2415 
   2416   /* Silently turn off flag_pic if not doing FDPIC or ID shared libraries,
   2417      since we don't support it and it'll just break.  */
   2418   if (flag_pic && !TARGET_FDPIC && !TARGET_ID_SHARED_LIBRARY)
   2419     flag_pic = 0;
   2420 
   2421   if (TARGET_MULTICORE && bfin_cpu_type != BFIN_CPU_BF561)
   2422     error ("%<-mmulticore%> can only be used with BF561");
   2423 
   2424   if (TARGET_COREA && !TARGET_MULTICORE)
   2425     error ("%<-mcorea%> should be used with %<-mmulticore%>");
   2426 
   2427   if (TARGET_COREB && !TARGET_MULTICORE)
   2428     error ("%<-mcoreb%> should be used with %<-mmulticore%>");
   2429 
   2430   if (TARGET_COREA && TARGET_COREB)
   2431     error ("%<-mcorea%> and %<-mcoreb%> cannot be used together");
   2432 
   2433   flag_schedule_insns = 0;
   2434 
   2435   init_machine_status = bfin_init_machine_status;
   2436 }
   2437 
   2438 /* Return the destination address of BRANCH.
   2439    We need to use this instead of get_attr_length, because the
   2440    cbranch_with_nops pattern conservatively sets its length to 6, and
   2441    we still prefer to use shorter sequences.  */
   2442 
   2443 static int
   2444 branch_dest (rtx_insn *branch)
   2445 {
   2446   rtx dest;
   2447   int dest_uid;
   2448   rtx pat = PATTERN (branch);
   2449   if (GET_CODE (pat) == PARALLEL)
   2450     pat = XVECEXP (pat, 0, 0);
   2451   dest = SET_SRC (pat);
   2452   if (GET_CODE (dest) == IF_THEN_ELSE)
   2453     dest = XEXP (dest, 1);
   2454   dest = XEXP (dest, 0);
   2455   dest_uid = INSN_UID (dest);
   2456   return INSN_ADDRESSES (dest_uid);
   2457 }
   2458 
   2459 /* Return nonzero if INSN is annotated with a REG_BR_PROB note that indicates
   2460    it's a branch that's predicted taken.  */
   2461 
   2462 static int
   2463 cbranch_predicted_taken_p (rtx insn)
   2464 {
   2465   rtx x = find_reg_note (insn, REG_BR_PROB, 0);
   2466 
   2467   if (x)
   2468     {
   2469       return profile_probability::from_reg_br_prob_note (XINT (x, 0))
   2470 	     >= profile_probability::even ();
   2471     }
   2472 
   2473   return 0;
   2474 }
   2475 
   2476 /* Templates for use by asm_conditional_branch.  */
   2477 
   2478 static const char *ccbranch_templates[][3] = {
   2479   { "if !cc jump %3;",  "if cc jump 4 (bp); jump.s %3;",  "if cc jump 6 (bp); jump.l %3;" },
   2480   { "if cc jump %3;",   "if !cc jump 4 (bp); jump.s %3;", "if !cc jump 6 (bp); jump.l %3;" },
   2481   { "if !cc jump %3 (bp);",  "if cc jump 4; jump.s %3;",  "if cc jump 6; jump.l %3;" },
   2482   { "if cc jump %3 (bp);",  "if !cc jump 4; jump.s %3;",  "if !cc jump 6; jump.l %3;" },
   2483 };
   2484 
   2485 /* Output INSN, which is a conditional branch instruction with operands
   2486    OPERANDS.
   2487 
   2488    We deal with the various forms of conditional branches that can be generated
   2489    by bfin_reorg to prevent the hardware from doing speculative loads, by
   2490    - emitting a sufficient number of nops, if N_NOPS is nonzero, or
   2491    - always emitting the branch as predicted taken, if PREDICT_TAKEN is true.
   2492    Either of these is only necessary if the branch is short, otherwise the
   2493    template we use ends in an unconditional jump which flushes the pipeline
   2494    anyway.  */
   2495 
   2496 void
   2497 asm_conditional_branch (rtx_insn *insn, rtx *operands, int n_nops, int predict_taken)
   2498 {
   2499   int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
   2500   /* Note : offset for instructions like if cc jmp; jump.[sl] offset
   2501             is to be taken from start of if cc rather than jump.
   2502             Range for jump.s is (-4094, 4096) instead of (-4096, 4094)
   2503   */
   2504   int len = (offset >= -1024 && offset <= 1022 ? 0
   2505 	     : offset >= -4094 && offset <= 4096 ? 1
   2506 	     : 2);
   2507   int bp = predict_taken && len == 0 ? 1 : cbranch_predicted_taken_p (insn);
   2508   int idx = (bp << 1) | (GET_CODE (operands[0]) == EQ ? BRF : BRT);
   2509   output_asm_insn (ccbranch_templates[idx][len], operands);
   2510   gcc_assert (n_nops == 0 || !bp);
   2511   if (len == 0)
   2512     while (n_nops-- > 0)
   2513       output_asm_insn ("nop;", NULL);
   2514 }
   2515 
   2516 /* Emit rtl for a comparison operation CMP in mode MODE.  Operands have been
   2517    stored in bfin_compare_op0 and bfin_compare_op1 already.  */
   2518 
   2519 rtx
   2520 bfin_gen_compare (rtx cmp, machine_mode mode ATTRIBUTE_UNUSED)
   2521 {
   2522   enum rtx_code code1, code2;
   2523   rtx op0 = XEXP (cmp, 0), op1 = XEXP (cmp, 1);
   2524   rtx tem = bfin_cc_rtx;
   2525   enum rtx_code code = GET_CODE (cmp);
   2526 
   2527   /* If we have a BImode input, then we already have a compare result, and
   2528      do not need to emit another comparison.  */
   2529   if (GET_MODE (op0) == BImode)
   2530     {
   2531       gcc_assert ((code == NE || code == EQ) && op1 == const0_rtx);
   2532       tem = op0, code2 = code;
   2533     }
   2534   else
   2535     {
   2536       switch (code) {
   2537 	/* bfin has these conditions */
   2538       case EQ:
   2539       case LT:
   2540       case LE:
   2541       case LEU:
   2542       case LTU:
   2543 	code1 = code;
   2544 	code2 = NE;
   2545 	break;
   2546       default:
   2547 	code1 = reverse_condition (code);
   2548 	code2 = EQ;
   2549 	break;
   2550       }
   2551       emit_insn (gen_rtx_SET (tem, gen_rtx_fmt_ee (code1, BImode, op0, op1)));
   2552     }
   2553 
   2554   return gen_rtx_fmt_ee (code2, BImode, tem, CONST0_RTX (BImode));
   2555 }
   2556 
   2557 /* Return nonzero iff C has exactly one bit set if it is interpreted
   2559    as a 32-bit constant.  */
   2560 
   2561 int
   2562 log2constp (unsigned HOST_WIDE_INT c)
   2563 {
   2564   c &= 0xFFFFFFFF;
   2565   return c != 0 && (c & (c-1)) == 0;
   2566 }
   2567 
   2568 /* Returns the number of consecutive least significant zeros in the binary
   2569    representation of *V.
   2570    We modify *V to contain the original value arithmetically shifted right by
   2571    the number of zeroes.  */
   2572 
   2573 static int
   2574 shiftr_zero (HOST_WIDE_INT *v)
   2575 {
   2576   unsigned HOST_WIDE_INT tmp = *v;
   2577   unsigned HOST_WIDE_INT sgn;
   2578   int n = 0;
   2579 
   2580   if (tmp == 0)
   2581     return 0;
   2582 
   2583   sgn = tmp & ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1));
   2584   while ((tmp & 0x1) == 0 && n <= 32)
   2585     {
   2586       tmp = (tmp >> 1) | sgn;
   2587       n++;
   2588     }
   2589   *v = tmp;
   2590   return n;
   2591 }
   2592 
   2593 /* After reload, split the load of an immediate constant.  OPERANDS are the
   2594    operands of the movsi_insn pattern which we are splitting.  We return
   2595    nonzero if we emitted a sequence to load the constant, zero if we emitted
   2596    nothing because we want to use the splitter's default sequence.  */
   2597 
   2598 int
   2599 split_load_immediate (rtx operands[])
   2600 {
   2601   HOST_WIDE_INT val = INTVAL (operands[1]);
   2602   HOST_WIDE_INT tmp;
   2603   HOST_WIDE_INT shifted = val;
   2604   HOST_WIDE_INT shifted_compl = ~val;
   2605   int num_zero = shiftr_zero (&shifted);
   2606   int num_compl_zero = shiftr_zero (&shifted_compl);
   2607   unsigned int regno = REGNO (operands[0]);
   2608 
   2609   /* This case takes care of single-bit set/clear constants, which we could
   2610      also implement with BITSET/BITCLR.  */
   2611   if (num_zero
   2612       && shifted >= -32768 && shifted < 65536
   2613       && (D_REGNO_P (regno)
   2614 	  || (regno >= REG_P0 && regno <= REG_P7 && num_zero <= 2)))
   2615     {
   2616       emit_insn (gen_movsi (operands[0], gen_int_mode (shifted, SImode)));
   2617       emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (num_zero)));
   2618       return 1;
   2619     }
   2620 
   2621   tmp = val & 0xFFFF;
   2622   tmp |= -(tmp & 0x8000);
   2623 
   2624   /* If high word has one bit set or clear, try to use a bit operation.  */
   2625   if (D_REGNO_P (regno))
   2626     {
   2627       if (log2constp (val & 0xFFFF0000))
   2628 	{
   2629 	  emit_insn (gen_movsi (operands[0], GEN_INT (val & 0xFFFF)));
   2630 	  emit_insn (gen_iorsi3 (operands[0], operands[0],
   2631 				 gen_int_mode (val & 0xFFFF0000, SImode)));
   2632 	  return 1;
   2633 	}
   2634       else if (log2constp (val | 0xFFFF) && (val & 0x8000) != 0)
   2635 	{
   2636 	  emit_insn (gen_movsi (operands[0], GEN_INT (tmp)));
   2637 	  emit_insn (gen_andsi3 (operands[0], operands[0],
   2638 				 gen_int_mode (val | 0xFFFF, SImode)));
   2639 	}
   2640     }
   2641 
   2642   if (D_REGNO_P (regno))
   2643     {
   2644       if (tmp >= -64 && tmp <= 63)
   2645 	{
   2646 	  emit_insn (gen_movsi (operands[0], GEN_INT (tmp)));
   2647 	  emit_insn (gen_movstricthi_high (operands[0],
   2648 					   gen_int_mode (val & -65536,
   2649 							 SImode)));
   2650 	  return 1;
   2651 	}
   2652 
   2653       if ((val & 0xFFFF0000) == 0)
   2654 	{
   2655 	  emit_insn (gen_movsi (operands[0], const0_rtx));
   2656 	  emit_insn (gen_movsi_low (operands[0], operands[0], operands[1]));
   2657 	  return 1;
   2658 	}
   2659 
   2660       if ((val & 0xFFFF0000) == 0xFFFF0000)
   2661 	{
   2662 	  emit_insn (gen_movsi (operands[0], constm1_rtx));
   2663 	  emit_insn (gen_movsi_low (operands[0], operands[0], operands[1]));
   2664 	  return 1;
   2665 	}
   2666     }
   2667 
   2668   /* Need DREGs for the remaining case.  */
   2669   if (regno > REG_R7)
   2670     return 0;
   2671 
   2672   if (optimize_size
   2673       && num_compl_zero && shifted_compl >= -64 && shifted_compl <= 63)
   2674     {
   2675       /* If optimizing for size, generate a sequence that has more instructions
   2676 	 but is shorter.  */
   2677       emit_insn (gen_movsi (operands[0], gen_int_mode (shifted_compl, SImode)));
   2678       emit_insn (gen_ashlsi3 (operands[0], operands[0],
   2679 			      GEN_INT (num_compl_zero)));
   2680       emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
   2681       return 1;
   2682     }
   2683   return 0;
   2684 }
   2685 
   2686 /* Return true if the legitimate memory address for a memory operand of mode
   2688    MODE.  Return false if not.  */
   2689 
   2690 static bool
   2691 bfin_valid_add (machine_mode mode, HOST_WIDE_INT value)
   2692 {
   2693   unsigned HOST_WIDE_INT v = value > 0 ? value : -value;
   2694   int sz = GET_MODE_SIZE (mode);
   2695   int shift = sz == 1 ? 0 : sz == 2 ? 1 : 2;
   2696   /* The usual offsettable_memref machinery doesn't work so well for this
   2697      port, so we deal with the problem here.  */
   2698   if (value > 0 && sz == 8)
   2699     v += 4;
   2700   return (v & ~(0x7fff << shift)) == 0;
   2701 }
   2702 
   2703 static bool
   2704 bfin_valid_reg_p (unsigned int regno, int strict, machine_mode mode,
   2705 		  enum rtx_code outer_code)
   2706 {
   2707   if (strict)
   2708     return REGNO_OK_FOR_BASE_STRICT_P (regno, mode, outer_code, SCRATCH);
   2709   else
   2710     return REGNO_OK_FOR_BASE_NONSTRICT_P (regno, mode, outer_code, SCRATCH);
   2711 }
   2712 
   2713 /* Recognize an RTL expression that is a valid memory address for an
   2714    instruction.  The MODE argument is the machine mode for the MEM expression
   2715    that wants to use this address.
   2716 
   2717    Blackfin addressing modes are as follows:
   2718 
   2719       [preg]
   2720       [preg + imm16]
   2721 
   2722       B [ Preg + uimm15 ]
   2723       W [ Preg + uimm16m2 ]
   2724       [ Preg + uimm17m4 ]
   2725 
   2726       [preg++]
   2727       [preg--]
   2728       [--sp]
   2729 */
   2730 
   2731 static bool
   2732 bfin_legitimate_address_p (machine_mode mode, rtx x, bool strict)
   2733 {
   2734   switch (GET_CODE (x)) {
   2735   case REG:
   2736     if (bfin_valid_reg_p (REGNO (x), strict, mode, MEM))
   2737       return true;
   2738     break;
   2739   case PLUS:
   2740     if (REG_P (XEXP (x, 0))
   2741 	&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, PLUS)
   2742 	&& ((GET_CODE (XEXP (x, 1)) == UNSPEC && mode == SImode)
   2743 	    || (GET_CODE (XEXP (x, 1)) == CONST_INT
   2744 		&& bfin_valid_add (mode, INTVAL (XEXP (x, 1))))))
   2745       return true;
   2746     break;
   2747   case POST_INC:
   2748   case POST_DEC:
   2749     if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
   2750 	&& REG_P (XEXP (x, 0))
   2751 	&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, POST_INC))
   2752       return true;
   2753     break;
   2754   case PRE_DEC:
   2755     if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
   2756 	&& XEXP (x, 0) == stack_pointer_rtx
   2757 	&& REG_P (XEXP (x, 0))
   2758 	&& bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, PRE_DEC))
   2759       return true;
   2760     break;
   2761   default:
   2762     break;
   2763   }
   2764   return false;
   2765 }
   2766 
   2767 /* Decide whether we can force certain constants to memory.  If we
   2768    decide we can't, the caller should be able to cope with it in
   2769    another way.  */
   2770 
   2771 static bool
   2772 bfin_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED,
   2773 			     rtx x ATTRIBUTE_UNUSED)
   2774 {
   2775   /* We have only one class of non-legitimate constants, and our movsi
   2776      expander knows how to handle them.  Dropping these constants into the
   2777      data section would only shift the problem - we'd still get relocs
   2778      outside the object, in the data section rather than the text section.  */
   2779   return true;
   2780 }
   2781 
   2782 /* Ensure that for any constant of the form symbol + offset, the offset
   2783    remains within the object.  Any other constants are ok.
   2784    This ensures that flat binaries never have to deal with relocations
   2785    crossing section boundaries.  */
   2786 
   2787 static bool
   2788 bfin_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
   2789 {
   2790   rtx sym;
   2791   HOST_WIDE_INT offset;
   2792 
   2793   if (GET_CODE (x) != CONST)
   2794     return true;
   2795 
   2796   x = XEXP (x, 0);
   2797   gcc_assert (GET_CODE (x) == PLUS);
   2798 
   2799   sym = XEXP (x, 0);
   2800   x = XEXP (x, 1);
   2801   if (GET_CODE (sym) != SYMBOL_REF
   2802       || GET_CODE (x) != CONST_INT)
   2803     return true;
   2804   offset = INTVAL (x);
   2805 
   2806   if (SYMBOL_REF_DECL (sym) == 0)
   2807     return true;
   2808   if (offset < 0
   2809       || offset >= int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (sym))))
   2810     return false;
   2811 
   2812   return true;
   2813 }
   2814 
   2815 static bool
   2816 bfin_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
   2817 		int *total, bool speed)
   2818 {
   2819   enum rtx_code code = GET_CODE (x);
   2820   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
   2821   int cost2 = COSTS_N_INSNS (1);
   2822   rtx op0, op1;
   2823 
   2824   switch (code)
   2825     {
   2826     case CONST_INT:
   2827       if (outer_code == SET || outer_code == PLUS)
   2828         *total = satisfies_constraint_Ks7 (x) ? 0 : cost2;
   2829       else if (outer_code == AND)
   2830         *total = log2constp (~INTVAL (x)) ? 0 : cost2;
   2831       else if (outer_code == LE || outer_code == LT || outer_code == EQ)
   2832         *total = (INTVAL (x) >= -4 && INTVAL (x) <= 3) ? 0 : cost2;
   2833       else if (outer_code == LEU || outer_code == LTU)
   2834         *total = (INTVAL (x) >= 0 && INTVAL (x) <= 7) ? 0 : cost2;
   2835       else if (outer_code == MULT)
   2836         *total = (INTVAL (x) == 2 || INTVAL (x) == 4) ? 0 : cost2;
   2837       else if (outer_code == ASHIFT && (INTVAL (x) == 1 || INTVAL (x) == 2))
   2838         *total = 0;
   2839       else if (outer_code == ASHIFT || outer_code == ASHIFTRT
   2840 	       || outer_code == LSHIFTRT)
   2841         *total = (INTVAL (x) >= 0 && INTVAL (x) <= 31) ? 0 : cost2;
   2842       else if (outer_code == IOR || outer_code == XOR)
   2843         *total = (INTVAL (x) & (INTVAL (x) - 1)) == 0 ? 0 : cost2;
   2844       else
   2845 	*total = cost2;
   2846       return true;
   2847 
   2848     case CONST:
   2849     case LABEL_REF:
   2850     case SYMBOL_REF:
   2851     case CONST_DOUBLE:
   2852       *total = COSTS_N_INSNS (2);
   2853       return true;
   2854 
   2855     case PLUS:
   2856       op0 = XEXP (x, 0);
   2857       op1 = XEXP (x, 1);
   2858       if (mode == SImode)
   2859 	{
   2860 	  if (GET_CODE (op0) == MULT
   2861 	      && GET_CODE (XEXP (op0, 1)) == CONST_INT)
   2862 	    {
   2863 	      HOST_WIDE_INT val = INTVAL (XEXP (op0, 1));
   2864 	      if (val == 2 || val == 4)
   2865 		{
   2866 		  *total = cost2;
   2867 		  *total += rtx_cost (XEXP (op0, 0), mode, outer_code,
   2868 				      opno, speed);
   2869 		  *total += rtx_cost (op1, mode, outer_code, opno, speed);
   2870 		  return true;
   2871 		}
   2872 	    }
   2873 	  *total = cost2;
   2874 	  if (GET_CODE (op0) != REG
   2875 	      && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
   2876 	    *total += set_src_cost (op0, mode, speed);
   2877 #if 0 /* We'd like to do this for accuracy, but it biases the loop optimizer
   2878 	 towards creating too many induction variables.  */
   2879 	  if (!reg_or_7bit_operand (op1, SImode))
   2880 	    *total += set_src_cost (op1, mode, speed);
   2881 #endif
   2882 	}
   2883       else if (mode == DImode)
   2884 	{
   2885 	  *total = 6 * cost2;
   2886 	  if (GET_CODE (op1) != CONST_INT
   2887 	      || !satisfies_constraint_Ks7 (op1))
   2888 	    *total += rtx_cost (op1, mode, PLUS, 1, speed);
   2889 	  if (GET_CODE (op0) != REG
   2890 	      && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
   2891 	    *total += rtx_cost (op0, mode, PLUS, 0, speed);
   2892 	}
   2893       return true;
   2894 
   2895     case MINUS:
   2896       if (mode == DImode)
   2897 	*total = 6 * cost2;
   2898       else
   2899 	*total = cost2;
   2900       return true;
   2901 
   2902     case ASHIFT:
   2903     case ASHIFTRT:
   2904     case LSHIFTRT:
   2905       if (mode == DImode)
   2906 	*total = 6 * cost2;
   2907       else
   2908 	*total = cost2;
   2909 
   2910       op0 = XEXP (x, 0);
   2911       op1 = XEXP (x, 1);
   2912       if (GET_CODE (op0) != REG
   2913 	  && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
   2914 	*total += rtx_cost (op0, mode, code, 0, speed);
   2915 
   2916       return true;
   2917 
   2918     case IOR:
   2919     case AND:
   2920     case XOR:
   2921       op0 = XEXP (x, 0);
   2922       op1 = XEXP (x, 1);
   2923 
   2924       /* Handle special cases of IOR: rotates, ALIGN insns, movstricthi_high.  */
   2925       if (code == IOR)
   2926 	{
   2927 	  if ((GET_CODE (op0) == LSHIFTRT && GET_CODE (op1) == ASHIFT)
   2928 	      || (GET_CODE (op0) == ASHIFT && GET_CODE (op1) == ZERO_EXTEND)
   2929 	      || (GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT)
   2930 	      || (GET_CODE (op0) == AND && GET_CODE (op1) == CONST_INT))
   2931 	    {
   2932 	      *total = cost2;
   2933 	      return true;
   2934 	    }
   2935 	}
   2936 
   2937       if (GET_CODE (op0) != REG
   2938 	  && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
   2939 	*total += rtx_cost (op0, mode, code, 0, speed);
   2940 
   2941       if (mode == DImode)
   2942 	{
   2943 	  *total = 2 * cost2;
   2944 	  return true;
   2945 	}
   2946       *total = cost2;
   2947       if (mode != SImode)
   2948 	return true;
   2949 
   2950       if (code == AND)
   2951 	{
   2952 	  if (! rhs_andsi3_operand (XEXP (x, 1), SImode))
   2953 	    *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   2954 	}
   2955       else
   2956 	{
   2957 	  if (! regorlog2_operand (XEXP (x, 1), SImode))
   2958 	    *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   2959 	}
   2960 
   2961       return true;
   2962 
   2963     case ZERO_EXTRACT:
   2964     case SIGN_EXTRACT:
   2965       if (outer_code == SET
   2966 	  && XEXP (x, 1) == const1_rtx
   2967 	  && GET_CODE (XEXP (x, 2)) == CONST_INT)
   2968 	{
   2969 	  *total = 2 * cost2;
   2970 	  return true;
   2971 	}
   2972       /* fall through */
   2973 
   2974     case SIGN_EXTEND:
   2975     case ZERO_EXTEND:
   2976       *total = cost2;
   2977       return true;
   2978 
   2979     case MULT:
   2980 	{
   2981 	  op0 = XEXP (x, 0);
   2982 	  op1 = XEXP (x, 1);
   2983 	  if (GET_CODE (op0) == GET_CODE (op1)
   2984 	      && (GET_CODE (op0) == ZERO_EXTEND
   2985 		  || GET_CODE (op0) == SIGN_EXTEND))
   2986 	    {
   2987 	      *total = COSTS_N_INSNS (1);
   2988 	      op0 = XEXP (op0, 0);
   2989 	      op1 = XEXP (op1, 0);
   2990 	    }
   2991 	  else if (!speed)
   2992 	    *total = COSTS_N_INSNS (1);
   2993 	  else
   2994 	    *total = COSTS_N_INSNS (3);
   2995 
   2996 	  if (GET_CODE (op0) != REG
   2997 	      && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
   2998 	    *total += rtx_cost (op0, mode, MULT, 0, speed);
   2999 	  if (GET_CODE (op1) != REG
   3000 	      && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
   3001 	    *total += rtx_cost (op1, mode, MULT, 1, speed);
   3002 	}
   3003       return true;
   3004 
   3005     case UDIV:
   3006     case UMOD:
   3007       *total = COSTS_N_INSNS (32);
   3008       return true;
   3009 
   3010     case VEC_CONCAT:
   3011     case VEC_SELECT:
   3012       if (outer_code == SET)
   3013 	*total = cost2;
   3014       return true;
   3015 
   3016     default:
   3017       return false;
   3018     }
   3019 }
   3020 
   3021 /* Used for communication between {push,pop}_multiple_operation (which
   3023    we use not only as a predicate) and the corresponding output functions.  */
   3024 static int first_preg_to_save, first_dreg_to_save;
   3025 static int n_regs_to_save;
   3026 
   3027 int
   3028 analyze_push_multiple_operation (rtx op)
   3029 {
   3030   int lastdreg = 8, lastpreg = 6;
   3031   int i, group;
   3032 
   3033   first_preg_to_save = lastpreg;
   3034   first_dreg_to_save = lastdreg;
   3035   for (i = 1, group = 0; i < XVECLEN (op, 0) - 1; i++)
   3036     {
   3037       rtx t = XVECEXP (op, 0, i);
   3038       rtx src, dest;
   3039       int regno;
   3040 
   3041       if (GET_CODE (t) != SET)
   3042 	return 0;
   3043 
   3044       src = SET_SRC (t);
   3045       dest = SET_DEST (t);
   3046       if (GET_CODE (dest) != MEM || ! REG_P (src))
   3047 	return 0;
   3048       dest = XEXP (dest, 0);
   3049       if (GET_CODE (dest) != PLUS
   3050 	  || ! REG_P (XEXP (dest, 0))
   3051 	  || REGNO (XEXP (dest, 0)) != REG_SP
   3052 	  || GET_CODE (XEXP (dest, 1)) != CONST_INT
   3053 	  || INTVAL (XEXP (dest, 1)) != -i * 4)
   3054 	return 0;
   3055 
   3056       regno = REGNO (src);
   3057       if (group == 0)
   3058 	{
   3059 	  if (D_REGNO_P (regno))
   3060 	    {
   3061 	      group = 1;
   3062 	      first_dreg_to_save = lastdreg = regno - REG_R0;
   3063 	    }
   3064 	  else if (regno >= REG_P0 && regno <= REG_P7)
   3065 	    {
   3066 	      group = 2;
   3067 	      first_preg_to_save = lastpreg = regno - REG_P0;
   3068 	    }
   3069 	  else
   3070 	    return 0;
   3071 
   3072 	  continue;
   3073 	}
   3074 
   3075       if (group == 1)
   3076 	{
   3077 	  if (regno >= REG_P0 && regno <= REG_P7)
   3078 	    {
   3079 	      group = 2;
   3080 	      first_preg_to_save = lastpreg = regno - REG_P0;
   3081 	    }
   3082 	  else if (regno != REG_R0 + lastdreg + 1)
   3083 	    return 0;
   3084 	  else
   3085 	    lastdreg++;
   3086 	}
   3087       else if (group == 2)
   3088 	{
   3089 	  if (regno != REG_P0 + lastpreg + 1)
   3090 	    return 0;
   3091 	  lastpreg++;
   3092 	}
   3093     }
   3094   n_regs_to_save = 8 - first_dreg_to_save + 6 - first_preg_to_save;
   3095   return 1;
   3096 }
   3097 
   3098 int
   3099 analyze_pop_multiple_operation (rtx op)
   3100 {
   3101   int lastdreg = 8, lastpreg = 6;
   3102   int i, group;
   3103 
   3104   for (i = 1, group = 0; i < XVECLEN (op, 0); i++)
   3105     {
   3106       rtx t = XVECEXP (op, 0, i);
   3107       rtx src, dest;
   3108       int regno;
   3109 
   3110       if (GET_CODE (t) != SET)
   3111 	return 0;
   3112 
   3113       src = SET_SRC (t);
   3114       dest = SET_DEST (t);
   3115       if (GET_CODE (src) != MEM || ! REG_P (dest))
   3116 	return 0;
   3117       src = XEXP (src, 0);
   3118 
   3119       if (i == 1)
   3120 	{
   3121 	  if (! REG_P (src) || REGNO (src) != REG_SP)
   3122 	    return 0;
   3123 	}
   3124       else if (GET_CODE (src) != PLUS
   3125 	       || ! REG_P (XEXP (src, 0))
   3126 	       || REGNO (XEXP (src, 0)) != REG_SP
   3127 	       || GET_CODE (XEXP (src, 1)) != CONST_INT
   3128 	       || INTVAL (XEXP (src, 1)) != (i - 1) * 4)
   3129 	return 0;
   3130 
   3131       regno = REGNO (dest);
   3132       if (group == 0)
   3133 	{
   3134 	  if (regno == REG_R7)
   3135 	    {
   3136 	      group = 1;
   3137 	      lastdreg = 7;
   3138 	    }
   3139 	  else if (regno != REG_P0 + lastpreg - 1)
   3140 	    return 0;
   3141 	  else
   3142 	    lastpreg--;
   3143 	}
   3144       else if (group == 1)
   3145 	{
   3146 	  if (regno != REG_R0 + lastdreg - 1)
   3147 	    return 0;
   3148 	  else
   3149 	    lastdreg--;
   3150 	}
   3151     }
   3152   first_dreg_to_save = lastdreg;
   3153   first_preg_to_save = lastpreg;
   3154   n_regs_to_save = 8 - first_dreg_to_save + 6 - first_preg_to_save;
   3155   return 1;
   3156 }
   3157 
   3158 /* Emit assembly code for one multi-register push described by INSN, with
   3159    operands in OPERANDS.  */
   3160 
   3161 void
   3162 output_push_multiple (rtx insn, rtx *operands)
   3163 {
   3164   char buf[80];
   3165   int ok;
   3166 
   3167   /* Validate the insn again, and compute first_[dp]reg_to_save. */
   3168   ok = analyze_push_multiple_operation (PATTERN (insn));
   3169   gcc_assert (ok);
   3170 
   3171   if (first_dreg_to_save == 8)
   3172     sprintf (buf, "[--sp] = ( p5:%d );\n", first_preg_to_save);
   3173   else if (first_preg_to_save == 6)
   3174     sprintf (buf, "[--sp] = ( r7:%d );\n", first_dreg_to_save);
   3175   else
   3176     sprintf (buf, "[--sp] = ( r7:%d, p5:%d );\n",
   3177 	     first_dreg_to_save, first_preg_to_save);
   3178 
   3179   output_asm_insn (buf, operands);
   3180 }
   3181 
   3182 /* Emit assembly code for one multi-register pop described by INSN, with
   3183    operands in OPERANDS.  */
   3184 
   3185 void
   3186 output_pop_multiple (rtx insn, rtx *operands)
   3187 {
   3188   char buf[80];
   3189   int ok;
   3190 
   3191   /* Validate the insn again, and compute first_[dp]reg_to_save. */
   3192   ok = analyze_pop_multiple_operation (PATTERN (insn));
   3193   gcc_assert (ok);
   3194 
   3195   if (first_dreg_to_save == 8)
   3196     sprintf (buf, "( p5:%d ) = [sp++];\n", first_preg_to_save);
   3197   else if (first_preg_to_save == 6)
   3198     sprintf (buf, "( r7:%d ) = [sp++];\n", first_dreg_to_save);
   3199   else
   3200     sprintf (buf, "( r7:%d, p5:%d ) = [sp++];\n",
   3201 	     first_dreg_to_save, first_preg_to_save);
   3202 
   3203   output_asm_insn (buf, operands);
   3204 }
   3205 
   3206 /* Adjust DST and SRC by OFFSET bytes, and generate one move in mode MODE.  */
   3207 
   3208 static void
   3209 single_move_for_cpymem (rtx dst, rtx src, machine_mode mode, HOST_WIDE_INT offset)
   3210 {
   3211   rtx scratch = gen_reg_rtx (mode);
   3212   rtx srcmem, dstmem;
   3213 
   3214   srcmem = adjust_address_nv (src, mode, offset);
   3215   dstmem = adjust_address_nv (dst, mode, offset);
   3216   emit_move_insn (scratch, srcmem);
   3217   emit_move_insn (dstmem, scratch);
   3218 }
   3219 
   3220 /* Expand a string move operation of COUNT_EXP bytes from SRC to DST, with
   3221    alignment ALIGN_EXP.  Return true if successful, false if we should fall
   3222    back on a different method.  */
   3223 
   3224 bool
   3225 bfin_expand_cpymem (rtx dst, rtx src, rtx count_exp, rtx align_exp)
   3226 {
   3227   rtx srcreg, destreg, countreg;
   3228   HOST_WIDE_INT align = 0;
   3229   unsigned HOST_WIDE_INT count = 0;
   3230 
   3231   if (GET_CODE (align_exp) == CONST_INT)
   3232     align = INTVAL (align_exp);
   3233   if (GET_CODE (count_exp) == CONST_INT)
   3234     {
   3235       count = INTVAL (count_exp);
   3236 #if 0
   3237       if (!TARGET_INLINE_ALL_STRINGOPS && count > 64)
   3238 	return false;
   3239 #endif
   3240     }
   3241 
   3242   /* If optimizing for size, only do single copies inline.  */
   3243   if (optimize_size)
   3244     {
   3245       if (count == 2 && align < 2)
   3246 	return false;
   3247       if (count == 4 && align < 4)
   3248 	return false;
   3249       if (count != 1 && count != 2 && count != 4)
   3250 	return false;
   3251     }
   3252   if (align < 2 && count != 1)
   3253     return false;
   3254 
   3255   destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
   3256   if (destreg != XEXP (dst, 0))
   3257     dst = replace_equiv_address_nv (dst, destreg);
   3258   srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
   3259   if (srcreg != XEXP (src, 0))
   3260     src = replace_equiv_address_nv (src, srcreg);
   3261 
   3262   if (count != 0 && align >= 2)
   3263     {
   3264       unsigned HOST_WIDE_INT offset = 0;
   3265 
   3266       if (align >= 4)
   3267 	{
   3268 	  if ((count & ~3) == 4)
   3269 	    {
   3270 	      single_move_for_cpymem (dst, src, SImode, offset);
   3271 	      offset = 4;
   3272 	    }
   3273 	  else if (count & ~3)
   3274 	    {
   3275 	      HOST_WIDE_INT new_count = ((count >> 2) & 0x3fffffff) - 1;
   3276 	      countreg = copy_to_mode_reg (Pmode, GEN_INT (new_count));
   3277 
   3278 	      emit_insn (gen_rep_movsi (destreg, srcreg, countreg, destreg, srcreg));
   3279 	      cfun->machine->has_loopreg_clobber = true;
   3280 	    }
   3281 	  if (count & 2)
   3282 	    {
   3283 	      single_move_for_cpymem (dst, src, HImode, offset);
   3284 	      offset += 2;
   3285 	    }
   3286 	}
   3287       else
   3288 	{
   3289 	  if ((count & ~1) == 2)
   3290 	    {
   3291 	      single_move_for_cpymem (dst, src, HImode, offset);
   3292 	      offset = 2;
   3293 	    }
   3294 	  else if (count & ~1)
   3295 	    {
   3296 	      HOST_WIDE_INT new_count = ((count >> 1) & 0x7fffffff) - 1;
   3297 	      countreg = copy_to_mode_reg (Pmode, GEN_INT (new_count));
   3298 
   3299 	      emit_insn (gen_rep_movhi (destreg, srcreg, countreg, destreg, srcreg));
   3300 	      cfun->machine->has_loopreg_clobber = true;
   3301 	    }
   3302 	}
   3303       if (count & 1)
   3304 	{
   3305 	  single_move_for_cpymem (dst, src, QImode, offset);
   3306 	}
   3307       return true;
   3308     }
   3309   return false;
   3310 }
   3311 
   3312 /* Compute the alignment for a local variable.
   3314    TYPE is the data type, and ALIGN is the alignment that
   3315    the object would ordinarily have.  The value of this macro is used
   3316    instead of that alignment to align the object.  */
   3317 
   3318 unsigned
   3319 bfin_local_alignment (tree type, unsigned align)
   3320 {
   3321   /* Increasing alignment for (relatively) big types allows the builtin
   3322      memcpy can use 32 bit loads/stores.  */
   3323   if (TYPE_SIZE (type)
   3324       && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   3325       && wi::gtu_p (wi::to_wide (TYPE_SIZE (type)), 8)
   3326       && align < 32)
   3327     return 32;
   3328   return align;
   3329 }
   3330 
   3331 /* Implement TARGET_SCHED_ISSUE_RATE.  */
   3333 
   3334 static int
   3335 bfin_issue_rate (void)
   3336 {
   3337   return 3;
   3338 }
   3339 
   3340 static int
   3341 bfin_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
   3342 		  unsigned int)
   3343 {
   3344   enum attr_type dep_insn_type;
   3345   int dep_insn_code_number;
   3346 
   3347   /* Anti and output dependencies have zero cost.  */
   3348   if (dep_type != 0)
   3349     return 0;
   3350 
   3351   dep_insn_code_number = recog_memoized (dep_insn);
   3352 
   3353   /* If we can't recognize the insns, we can't really do anything.  */
   3354   if (dep_insn_code_number < 0 || recog_memoized (insn) < 0)
   3355     return cost;
   3356 
   3357   dep_insn_type = get_attr_type (dep_insn);
   3358 
   3359   if (dep_insn_type == TYPE_MOVE || dep_insn_type == TYPE_MCLD)
   3360     {
   3361       rtx pat = PATTERN (dep_insn);
   3362       rtx dest, src;
   3363 
   3364       if (GET_CODE (pat) == PARALLEL)
   3365 	pat = XVECEXP (pat, 0, 0);
   3366       dest = SET_DEST (pat);
   3367       src = SET_SRC (pat);
   3368       if (! ADDRESS_REGNO_P (REGNO (dest))
   3369 	  || ! (MEM_P (src) || D_REGNO_P (REGNO (src))))
   3370 	return cost;
   3371       return cost + (dep_insn_type == TYPE_MOVE ? 4 : 3);
   3372     }
   3373 
   3374   return cost;
   3375 }
   3376 
   3377 /* This function acts like NEXT_INSN, but is aware of three-insn bundles and
   3379    skips all subsequent parallel instructions if INSN is the start of such
   3380    a group.  */
   3381 static rtx_insn *
   3382 find_next_insn_start (rtx_insn *insn)
   3383 {
   3384   if (GET_MODE (insn) == SImode)
   3385     {
   3386       while (GET_MODE (insn) != QImode)
   3387 	insn = NEXT_INSN (insn);
   3388     }
   3389   return NEXT_INSN (insn);
   3390 }
   3391 
   3392 /* This function acts like PREV_INSN, but is aware of three-insn bundles and
   3393    skips all subsequent parallel instructions if INSN is the start of such
   3394    a group.  */
   3395 static rtx_insn *
   3396 find_prev_insn_start (rtx_insn *insn)
   3397 {
   3398   insn = PREV_INSN (insn);
   3399   gcc_assert (GET_MODE (insn) != SImode);
   3400   if (GET_MODE (insn) == QImode)
   3401     {
   3402       while (GET_MODE (PREV_INSN (insn)) == SImode)
   3403 	insn = PREV_INSN (insn);
   3404     }
   3405   return insn;
   3406 }
   3407 
   3408 /* Implement TARGET_CAN_USE_DOLOOP_P.  */
   3410 
   3411 static bool
   3412 bfin_can_use_doloop_p (const widest_int &, const widest_int &iterations_max,
   3413 		       unsigned int, bool)
   3414 {
   3415   /* Due to limitations in the hardware (an initial loop count of 0
   3416      does not loop 2^32 times) we must avoid to generate a hardware
   3417      loops when we cannot rule out this case.  */
   3418   return (wi::ltu_p (iterations_max, 0xFFFFFFFF));
   3419 }
   3420 
   3421 /* Increment the counter for the number of loop instructions in the
   3422    current function.  */
   3423 
   3424 void
   3425 bfin_hardware_loop (void)
   3426 {
   3427   cfun->machine->has_hardware_loops++;
   3428 }
   3429 
   3430 /* Maximum loop nesting depth.  */
   3431 #define MAX_LOOP_DEPTH 2
   3432 
   3433 /* Maximum size of a loop.  */
   3434 #define MAX_LOOP_LENGTH 2042
   3435 
   3436 /* Maximum distance of the LSETUP instruction from the loop start.  */
   3437 #define MAX_LSETUP_DISTANCE 30
   3438 
   3439 /* Estimate the length of INSN conservatively.  */
   3440 
   3441 static int
   3442 length_for_loop (rtx_insn *insn)
   3443 {
   3444   int length = 0;
   3445   if (JUMP_P (insn) && any_condjump_p (insn) && !optimize_size)
   3446     {
   3447       if (ENABLE_WA_SPECULATIVE_SYNCS)
   3448 	length = 8;
   3449       else if (ENABLE_WA_SPECULATIVE_LOADS)
   3450 	length = 6;
   3451     }
   3452   else if (LABEL_P (insn))
   3453     {
   3454       if (ENABLE_WA_SPECULATIVE_SYNCS)
   3455 	length = 4;
   3456     }
   3457 
   3458   if (NONDEBUG_INSN_P (insn))
   3459     length += get_attr_length (insn);
   3460 
   3461   return length;
   3462 }
   3463 
   3464 /* Optimize LOOP.  */
   3465 
   3466 static bool
   3467 hwloop_optimize (hwloop_info loop)
   3468 {
   3469   basic_block bb;
   3470   rtx_insn *insn, *last_insn;
   3471   rtx loop_init, start_label, end_label;
   3472   rtx iter_reg, scratchreg, scratch_init;
   3473   rtx_insn *scratch_init_insn;
   3474   rtx lc_reg, lt_reg, lb_reg;
   3475   rtx seq_end;
   3476   rtx_insn *seq;
   3477   int length;
   3478   bool clobber0, clobber1;
   3479 
   3480   if (loop->depth > MAX_LOOP_DEPTH)
   3481     {
   3482       if (dump_file)
   3483 	fprintf (dump_file, ";; loop %d too deep\n", loop->loop_no);
   3484       return false;
   3485     }
   3486 
   3487   /* Get the loop iteration register.  */
   3488   iter_reg = loop->iter_reg;
   3489 
   3490   gcc_assert (REG_P (iter_reg));
   3491 
   3492   scratchreg = NULL_RTX;
   3493   scratch_init = iter_reg;
   3494   scratch_init_insn = NULL;
   3495   if (!PREG_P (iter_reg) && loop->incoming_src)
   3496     {
   3497       basic_block bb_in = loop->incoming_src;
   3498       int i;
   3499       for (i = REG_P0; i <= REG_P5; i++)
   3500 	if ((df_regs_ever_live_p (i)
   3501 	     || (funkind (TREE_TYPE (current_function_decl)) == SUBROUTINE
   3502 		 && call_used_or_fixed_reg_p (i)))
   3503 	    && !REGNO_REG_SET_P (df_get_live_out (bb_in), i))
   3504 	  {
   3505 	    scratchreg = gen_rtx_REG (SImode, i);
   3506 	    break;
   3507 	  }
   3508       for (insn = BB_END (bb_in); insn != BB_HEAD (bb_in);
   3509 	   insn = PREV_INSN (insn))
   3510 	{
   3511 	  rtx set;
   3512 	  if (NOTE_P (insn) || BARRIER_P (insn))
   3513 	    continue;
   3514 	  set = single_set (insn);
   3515 	  if (set && rtx_equal_p (SET_DEST (set), iter_reg))
   3516 	    {
   3517 	      if (CONSTANT_P (SET_SRC (set)))
   3518 		{
   3519 		  scratch_init = SET_SRC (set);
   3520 		  scratch_init_insn = insn;
   3521 		}
   3522 	      break;
   3523 	    }
   3524 	  else if (reg_mentioned_p (iter_reg, PATTERN (insn)))
   3525 	    break;
   3526 	}
   3527     }
   3528 
   3529   if (loop->incoming_src)
   3530     {
   3531       /* Make sure the predecessor is before the loop start label, as required by
   3532 	 the LSETUP instruction.  */
   3533       length = 0;
   3534       insn = BB_END (loop->incoming_src);
   3535       /* If we have to insert the LSETUP before a jump, count that jump in the
   3536 	 length.  */
   3537       if (vec_safe_length (loop->incoming) > 1
   3538 	  || !(loop->incoming->last ()->flags & EDGE_FALLTHRU))
   3539 	{
   3540 	  gcc_assert (JUMP_P (insn));
   3541 	  insn = PREV_INSN (insn);
   3542 	}
   3543 
   3544       for (; insn && insn != loop->start_label; insn = NEXT_INSN (insn))
   3545 	length += length_for_loop (insn);
   3546 
   3547       if (!insn)
   3548 	{
   3549 	  if (dump_file)
   3550 	    fprintf (dump_file, ";; loop %d lsetup not before loop_start\n",
   3551 		     loop->loop_no);
   3552 	  return false;
   3553 	}
   3554 
   3555       /* Account for the pop of a scratch register where necessary.  */
   3556       if (!PREG_P (iter_reg) && scratchreg == NULL_RTX
   3557 	  && ENABLE_WA_LOAD_LCREGS)
   3558 	length += 2;
   3559 
   3560       if (length > MAX_LSETUP_DISTANCE)
   3561 	{
   3562 	  if (dump_file)
   3563 	    fprintf (dump_file, ";; loop %d lsetup too far away\n", loop->loop_no);
   3564 	  return false;
   3565 	}
   3566     }
   3567 
   3568   /* Check if start_label appears before loop_end and calculate the
   3569      offset between them.  We calculate the length of instructions
   3570      conservatively.  */
   3571   length = 0;
   3572   for (insn = loop->start_label;
   3573        insn && insn != loop->loop_end;
   3574        insn = NEXT_INSN (insn))
   3575     length += length_for_loop (insn);
   3576 
   3577   if (!insn)
   3578     {
   3579       if (dump_file)
   3580 	fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
   3581 		 loop->loop_no);
   3582       return false;
   3583     }
   3584 
   3585   loop->length = length;
   3586   if (loop->length > MAX_LOOP_LENGTH)
   3587     {
   3588       if (dump_file)
   3589 	fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
   3590       return false;
   3591     }
   3592 
   3593   /* Scan all the blocks to make sure they don't use iter_reg.  */
   3594   if (loop->iter_reg_used || loop->iter_reg_used_outside)
   3595     {
   3596       if (dump_file)
   3597 	fprintf (dump_file, ";; loop %d uses iterator\n", loop->loop_no);
   3598       return false;
   3599     }
   3600 
   3601   clobber0 = (TEST_HARD_REG_BIT (loop->regs_set_in_loop, REG_LC0)
   3602 	      || TEST_HARD_REG_BIT (loop->regs_set_in_loop, REG_LB0)
   3603 	      || TEST_HARD_REG_BIT (loop->regs_set_in_loop, REG_LT0));
   3604   clobber1 = (TEST_HARD_REG_BIT (loop->regs_set_in_loop, REG_LC1)
   3605 	      || TEST_HARD_REG_BIT (loop->regs_set_in_loop, REG_LB1)
   3606 	      || TEST_HARD_REG_BIT (loop->regs_set_in_loop, REG_LT1));
   3607   if (clobber0 && clobber1)
   3608     {
   3609       if (dump_file)
   3610 	fprintf (dump_file, ";; loop %d no loop reg available\n",
   3611 		 loop->loop_no);
   3612       return false;
   3613     }
   3614 
   3615   /* There should be an instruction before the loop_end instruction
   3616      in the same basic block. And the instruction must not be
   3617      - JUMP
   3618      - CONDITIONAL BRANCH
   3619      - CALL
   3620      - CSYNC
   3621      - SSYNC
   3622      - Returns (RTS, RTN, etc.)  */
   3623 
   3624   bb = loop->tail;
   3625   last_insn = find_prev_insn_start (loop->loop_end);
   3626 
   3627   while (1)
   3628     {
   3629       for (; last_insn != BB_HEAD (bb);
   3630 	   last_insn = find_prev_insn_start (last_insn))
   3631 	if (NONDEBUG_INSN_P (last_insn))
   3632 	  break;
   3633 
   3634       if (last_insn != BB_HEAD (bb))
   3635 	break;
   3636 
   3637       if (single_pred_p (bb)
   3638 	  && single_pred_edge (bb)->flags & EDGE_FALLTHRU
   3639 	  && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
   3640 	{
   3641 	  bb = single_pred (bb);
   3642 	  last_insn = BB_END (bb);
   3643 	  continue;
   3644 	}
   3645       else
   3646 	{
   3647 	  last_insn = NULL;
   3648 	  break;
   3649 	}
   3650     }
   3651 
   3652   if (!last_insn)
   3653     {
   3654       if (dump_file)
   3655 	fprintf (dump_file, ";; loop %d has no last instruction\n",
   3656 		 loop->loop_no);
   3657       return false;
   3658     }
   3659 
   3660   if (JUMP_P (last_insn) && !any_condjump_p (last_insn))
   3661     {
   3662       if (dump_file)
   3663 	fprintf (dump_file, ";; loop %d has bad last instruction\n",
   3664 		 loop->loop_no);
   3665       return false;
   3666     }
   3667   /* In all other cases, try to replace a bad last insn with a nop.  */
   3668   else if (JUMP_P (last_insn)
   3669 	   || CALL_P (last_insn)
   3670 	   || get_attr_type (last_insn) == TYPE_SYNC
   3671 	   || get_attr_type (last_insn) == TYPE_CALL
   3672 	   || get_attr_seq_insns (last_insn) == SEQ_INSNS_MULTI
   3673 	   || recog_memoized (last_insn) == CODE_FOR_return_internal
   3674 	   || GET_CODE (PATTERN (last_insn)) == ASM_INPUT
   3675 	   || asm_noperands (PATTERN (last_insn)) >= 0)
   3676     {
   3677       if (loop->length + 2 > MAX_LOOP_LENGTH)
   3678 	{
   3679 	  if (dump_file)
   3680 	    fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
   3681 	  return false;
   3682 	}
   3683       if (dump_file)
   3684 	fprintf (dump_file, ";; loop %d has bad last insn; replace with nop\n",
   3685 		 loop->loop_no);
   3686 
   3687       last_insn = emit_insn_after (gen_forced_nop (), last_insn);
   3688     }
   3689 
   3690   loop->last_insn = last_insn;
   3691 
   3692   /* The loop is good for replacement.  */
   3693   start_label = loop->start_label;
   3694   end_label = gen_label_rtx ();
   3695   iter_reg = loop->iter_reg;
   3696 
   3697   if (loop->depth == 1 && !clobber1)
   3698     {
   3699       lc_reg = gen_rtx_REG (SImode, REG_LC1);
   3700       lb_reg = gen_rtx_REG (SImode, REG_LB1);
   3701       lt_reg = gen_rtx_REG (SImode, REG_LT1);
   3702       SET_HARD_REG_BIT (loop->regs_set_in_loop, REG_LC1);
   3703     }
   3704   else
   3705     {
   3706       lc_reg = gen_rtx_REG (SImode, REG_LC0);
   3707       lb_reg = gen_rtx_REG (SImode, REG_LB0);
   3708       lt_reg = gen_rtx_REG (SImode, REG_LT0);
   3709       SET_HARD_REG_BIT (loop->regs_set_in_loop, REG_LC0);
   3710     }
   3711 
   3712   loop->end_label = end_label;
   3713 
   3714   /* Create a sequence containing the loop setup.  */
   3715   start_sequence ();
   3716 
   3717   /* LSETUP only accepts P registers.  If we have one, we can use it,
   3718      otherwise there are several ways of working around the problem.
   3719      If we're not affected by anomaly 312, we can load the LC register
   3720      from any iteration register, and use LSETUP without initialization.
   3721      If we've found a P scratch register that's not live here, we can
   3722      instead copy the iter_reg into that and use an initializing LSETUP.
   3723      If all else fails, push and pop P0 and use it as a scratch.  */
   3724   if (P_REGNO_P (REGNO (iter_reg)))
   3725     {
   3726       loop_init = gen_lsetup_with_autoinit (lt_reg, start_label,
   3727 					    lb_reg, end_label,
   3728 					    lc_reg, iter_reg);
   3729       seq_end = emit_insn (loop_init);
   3730     }
   3731   else if (!ENABLE_WA_LOAD_LCREGS && DPREG_P (iter_reg))
   3732     {
   3733       emit_insn (gen_movsi (lc_reg, iter_reg));
   3734       loop_init = gen_lsetup_without_autoinit (lt_reg, start_label,
   3735 					       lb_reg, end_label,
   3736 					       lc_reg);
   3737       seq_end = emit_insn (loop_init);
   3738     }
   3739   else if (scratchreg != NULL_RTX)
   3740     {
   3741       emit_insn (gen_movsi (scratchreg, scratch_init));
   3742       loop_init = gen_lsetup_with_autoinit (lt_reg, start_label,
   3743 					    lb_reg, end_label,
   3744 					    lc_reg, scratchreg);
   3745       seq_end = emit_insn (loop_init);
   3746       if (scratch_init_insn != NULL_RTX)
   3747 	delete_insn (scratch_init_insn);
   3748     }
   3749   else
   3750     {
   3751       rtx p0reg = gen_rtx_REG (SImode, REG_P0);
   3752       rtx push = gen_frame_mem (SImode,
   3753 				gen_rtx_PRE_DEC (SImode, stack_pointer_rtx));
   3754       rtx pop = gen_frame_mem (SImode,
   3755 			       gen_rtx_POST_INC (SImode, stack_pointer_rtx));
   3756       emit_insn (gen_movsi (push, p0reg));
   3757       emit_insn (gen_movsi (p0reg, scratch_init));
   3758       loop_init = gen_lsetup_with_autoinit (lt_reg, start_label,
   3759 					    lb_reg, end_label,
   3760 					    lc_reg, p0reg);
   3761       emit_insn (loop_init);
   3762       seq_end = emit_insn (gen_movsi (p0reg, pop));
   3763       if (scratch_init_insn != NULL_RTX)
   3764 	delete_insn (scratch_init_insn);
   3765     }
   3766 
   3767   if (dump_file)
   3768     {
   3769       fprintf (dump_file, ";; replacing loop %d initializer with\n",
   3770 	       loop->loop_no);
   3771       print_rtl_single (dump_file, loop_init);
   3772       fprintf (dump_file, ";; replacing loop %d terminator with\n",
   3773 	       loop->loop_no);
   3774       print_rtl_single (dump_file, loop->loop_end);
   3775     }
   3776 
   3777   /* If the loop isn't entered at the top, also create a jump to the entry
   3778      point.  */
   3779   if (!loop->incoming_src && loop->head != loop->incoming_dest)
   3780     {
   3781       rtx_insn *label = BB_HEAD (loop->incoming_dest);
   3782       /* If we're jumping to the final basic block in the loop, and there's
   3783 	 only one cheap instruction before the end (typically an increment of
   3784 	 an induction variable), we can just emit a copy here instead of a
   3785 	 jump.  */
   3786       if (loop->incoming_dest == loop->tail
   3787 	  && next_real_insn (label) == last_insn
   3788 	  && asm_noperands (last_insn) < 0
   3789 	  && GET_CODE (PATTERN (last_insn)) == SET)
   3790 	{
   3791 	  seq_end = emit_insn (copy_rtx (PATTERN (last_insn)));
   3792 	}
   3793       else
   3794 	{
   3795 	  rtx_insn *ret = emit_jump_insn (gen_jump (label));
   3796 	  JUMP_LABEL (ret) = label;
   3797 	  LABEL_NUSES (label)++;
   3798 	  seq_end = emit_barrier ();
   3799 	}
   3800     }
   3801 
   3802   seq = get_insns ();
   3803   end_sequence ();
   3804 
   3805   if (loop->incoming_src)
   3806     {
   3807       rtx_insn *prev = BB_END (loop->incoming_src);
   3808       if (vec_safe_length (loop->incoming) > 1
   3809 	  || !(loop->incoming->last ()->flags & EDGE_FALLTHRU))
   3810 	{
   3811 	  gcc_assert (JUMP_P (prev));
   3812 	  prev = PREV_INSN (prev);
   3813 	  emit_insn_after (seq, prev);
   3814 	}
   3815       else
   3816 	{
   3817 	  emit_insn_after (seq, prev);
   3818 	  BB_END (loop->incoming_src) = prev;
   3819 	  basic_block new_bb = create_basic_block (seq, seq_end,
   3820 						   loop->head->prev_bb);
   3821 	  edge e = loop->incoming->last ();
   3822 	  gcc_assert (e->flags & EDGE_FALLTHRU);
   3823 	  redirect_edge_succ (e, new_bb);
   3824 	  make_edge (new_bb, loop->head, 0);
   3825 	}
   3826     }
   3827   else
   3828     {
   3829       basic_block new_bb;
   3830       edge e;
   3831       edge_iterator ei;
   3832 
   3833       if (flag_checking && loop->head != loop->incoming_dest)
   3834 	{
   3835 	  /* We aren't entering the loop at the top.  Since we've established
   3836 	     that the loop is entered only at one point, this means there
   3837 	     can't be fallthru edges into the head.  Any such fallthru edges
   3838 	     would become invalid when we insert the new block, so verify
   3839 	     that this does not in fact happen.  */
   3840 	  FOR_EACH_EDGE (e, ei, loop->head->preds)
   3841 	    gcc_assert (!(e->flags & EDGE_FALLTHRU));
   3842 	}
   3843 
   3844       emit_insn_before (seq, BB_HEAD (loop->head));
   3845       seq = emit_label_before (gen_label_rtx (), seq);
   3846 
   3847       new_bb = create_basic_block (seq, seq_end, loop->head->prev_bb);
   3848       FOR_EACH_EDGE (e, ei, loop->incoming)
   3849 	{
   3850 	  if (!(e->flags & EDGE_FALLTHRU)
   3851 	      || e->dest != loop->head)
   3852 	    redirect_edge_and_branch_force (e, new_bb);
   3853 	  else
   3854 	    redirect_edge_succ (e, new_bb);
   3855 	}
   3856       e = make_edge (new_bb, loop->head, 0);
   3857     }
   3858 
   3859   delete_insn (loop->loop_end);
   3860   /* Insert the loop end label before the last instruction of the loop.  */
   3861   emit_label_before (as_a <rtx_code_label *> (loop->end_label),
   3862 		     loop->last_insn);
   3863 
   3864   return true;
   3865 }
   3866 
   3867 /* A callback for the hw-doloop pass.  Called when a loop we have discovered
   3868    turns out not to be optimizable; we have to split the doloop_end pattern
   3869    into a subtract and a test.  */
   3870 static void
   3871 hwloop_fail (hwloop_info loop)
   3872 {
   3873   rtx insn = loop->loop_end;
   3874 
   3875   if (DPREG_P (loop->iter_reg))
   3876     {
   3877       /* If loop->iter_reg is a DREG or PREG, we can split it here
   3878 	 without scratch register.  */
   3879       rtx insn, test;
   3880 
   3881       emit_insn_before (gen_addsi3 (loop->iter_reg,
   3882 				    loop->iter_reg,
   3883 				    constm1_rtx),
   3884 			loop->loop_end);
   3885 
   3886       test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
   3887       insn = emit_jump_insn_before (gen_cbranchsi4 (test,
   3888 						    loop->iter_reg, const0_rtx,
   3889 						    loop->start_label),
   3890 				    loop->loop_end);
   3891 
   3892       JUMP_LABEL (insn) = loop->start_label;
   3893       LABEL_NUSES (loop->start_label)++;
   3894       delete_insn (loop->loop_end);
   3895     }
   3896   else
   3897     {
   3898       splitting_loops = 1;
   3899       try_split (PATTERN (insn), safe_as_a <rtx_insn *> (insn), 1);
   3900       splitting_loops = 0;
   3901     }
   3902 }
   3903 
   3904 /* A callback for the hw-doloop pass.  This function examines INSN; if
   3905    it is a loop_end pattern we recognize, return the reg rtx for the
   3906    loop counter.  Otherwise, return NULL_RTX.  */
   3907 
   3908 static rtx
   3909 hwloop_pattern_reg (rtx_insn *insn)
   3910 {
   3911   rtx reg;
   3912 
   3913   if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
   3914     return NULL_RTX;
   3915 
   3916   reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
   3917   if (!REG_P (reg))
   3918     return NULL_RTX;
   3919   return reg;
   3920 }
   3921 
   3922 static struct hw_doloop_hooks bfin_doloop_hooks =
   3923 {
   3924   hwloop_pattern_reg,
   3925   hwloop_optimize,
   3926   hwloop_fail
   3927 };
   3928 
   3929 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
   3930    and tries to rewrite the RTL of these loops so that proper Blackfin
   3931    hardware loops are generated.  */
   3932 
   3933 static void
   3934 bfin_reorg_loops (void)
   3935 {
   3936   reorg_loops (true, &bfin_doloop_hooks);
   3937 }
   3938 
   3939 /* Possibly generate a SEQUENCE out of three insns found in SLOT.
   3941    Returns true if we modified the insn chain, false otherwise.  */
   3942 static bool
   3943 gen_one_bundle (rtx_insn *slot[3])
   3944 {
   3945   gcc_assert (slot[1] != NULL_RTX);
   3946 
   3947   /* Don't add extra NOPs if optimizing for size.  */
   3948   if (optimize_size
   3949       && (slot[0] == NULL_RTX || slot[2] == NULL_RTX))
   3950     return false;
   3951 
   3952   /* Verify that we really can do the multi-issue.  */
   3953   if (slot[0])
   3954     {
   3955       rtx_insn *t = NEXT_INSN (slot[0]);
   3956       while (t != slot[1])
   3957 	{
   3958 	  if (! NOTE_P (t) || NOTE_KIND (t) != NOTE_INSN_DELETED)
   3959 	    return false;
   3960 	  t = NEXT_INSN (t);
   3961 	}
   3962     }
   3963   if (slot[2])
   3964     {
   3965       rtx_insn *t = NEXT_INSN (slot[1]);
   3966       while (t != slot[2])
   3967 	{
   3968 	  if (! NOTE_P (t) || NOTE_KIND (t) != NOTE_INSN_DELETED)
   3969 	    return false;
   3970 	  t = NEXT_INSN (t);
   3971 	}
   3972     }
   3973 
   3974   if (slot[0] == NULL_RTX)
   3975     {
   3976       slot[0] = emit_insn_before (gen_mnop (), slot[1]);
   3977       df_insn_rescan (slot[0]);
   3978     }
   3979   if (slot[2] == NULL_RTX)
   3980     {
   3981       slot[2] = emit_insn_after (gen_forced_nop (), slot[1]);
   3982       df_insn_rescan (slot[2]);
   3983     }
   3984 
   3985   /* Avoid line number information being printed inside one bundle.  */
   3986   if (INSN_LOCATION (slot[1])
   3987       && INSN_LOCATION (slot[1]) != INSN_LOCATION (slot[0]))
   3988     INSN_LOCATION (slot[1]) = INSN_LOCATION (slot[0]);
   3989   if (INSN_LOCATION (slot[2])
   3990       && INSN_LOCATION (slot[2]) != INSN_LOCATION (slot[0]))
   3991     INSN_LOCATION (slot[2]) = INSN_LOCATION (slot[0]);
   3992 
   3993   /* Terminate them with "|| " instead of ";" in the output.  */
   3994   PUT_MODE (slot[0], SImode);
   3995   PUT_MODE (slot[1], SImode);
   3996   /* Terminate the bundle, for the benefit of reorder_var_tracking_notes.  */
   3997   PUT_MODE (slot[2], QImode);
   3998   return true;
   3999 }
   4000 
   4001 /* Go through all insns, and use the information generated during scheduling
   4002    to generate SEQUENCEs to represent bundles of instructions issued
   4003    simultaneously.  */
   4004 
   4005 static void
   4006 bfin_gen_bundles (void)
   4007 {
   4008   basic_block bb;
   4009   FOR_EACH_BB_FN (bb, cfun)
   4010     {
   4011       rtx_insn *insn, *next;
   4012       rtx_insn *slot[3];
   4013       int n_filled = 0;
   4014 
   4015       slot[0] = slot[1] = slot[2] = NULL;
   4016       for (insn = BB_HEAD (bb);; insn = next)
   4017 	{
   4018 	  int at_end;
   4019 	  rtx_insn *delete_this = NULL;
   4020 
   4021 	  if (NONDEBUG_INSN_P (insn))
   4022 	    {
   4023 	      enum attr_type type = get_attr_type (insn);
   4024 
   4025 	      if (type == TYPE_STALL)
   4026 		{
   4027 		  gcc_assert (n_filled == 0);
   4028 		  delete_this = insn;
   4029 		}
   4030 	      else
   4031 		{
   4032 		  if (type == TYPE_DSP32 || type == TYPE_DSP32SHIFTIMM)
   4033 		    slot[0] = insn;
   4034 		  else if (slot[1] == NULL_RTX)
   4035 		    slot[1] = insn;
   4036 		  else
   4037 		    slot[2] = insn;
   4038 		  n_filled++;
   4039 		}
   4040 	    }
   4041 
   4042 	  next = NEXT_INSN (insn);
   4043 	  while (next && insn != BB_END (bb)
   4044 		 && !(INSN_P (next)
   4045 		      && GET_CODE (PATTERN (next)) != USE
   4046 		      && GET_CODE (PATTERN (next)) != CLOBBER))
   4047 	    {
   4048 	      insn = next;
   4049 	      next = NEXT_INSN (insn);
   4050 	    }
   4051 
   4052 	  /* BB_END can change due to emitting extra NOPs, so check here.  */
   4053 	  at_end = insn == BB_END (bb);
   4054 	  if (delete_this == NULL_RTX && (at_end || GET_MODE (next) == TImode))
   4055 	    {
   4056 	      if ((n_filled < 2
   4057 		   || !gen_one_bundle (slot))
   4058 		  && slot[0] != NULL_RTX)
   4059 		{
   4060 		  rtx pat = PATTERN (slot[0]);
   4061 		  if (GET_CODE (pat) == SET
   4062 		      && GET_CODE (SET_SRC (pat)) == UNSPEC
   4063 		      && XINT (SET_SRC (pat), 1) == UNSPEC_32BIT)
   4064 		    {
   4065 		      SET_SRC (pat) = XVECEXP (SET_SRC (pat), 0, 0);
   4066 		      INSN_CODE (slot[0]) = -1;
   4067 		      df_insn_rescan (slot[0]);
   4068 		    }
   4069 		}
   4070 	      n_filled = 0;
   4071 	      slot[0] = slot[1] = slot[2] = NULL;
   4072 	    }
   4073 	  if (delete_this != NULL_RTX)
   4074 	    delete_insn (delete_this);
   4075 	  if (at_end)
   4076 	    break;
   4077 	}
   4078     }
   4079 }
   4080 
   4081 /* Ensure that no var tracking notes are emitted in the middle of a
   4082    three-instruction bundle.  */
   4083 
   4084 static void
   4085 reorder_var_tracking_notes (void)
   4086 {
   4087   basic_block bb;
   4088   FOR_EACH_BB_FN (bb, cfun)
   4089     {
   4090       rtx_insn *insn, *next;
   4091       rtx_insn *queue = NULL;
   4092       bool in_bundle = false;
   4093 
   4094       for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = next)
   4095 	{
   4096 	  next = NEXT_INSN (insn);
   4097 
   4098 	  if (INSN_P (insn))
   4099 	    {
   4100 	      /* Emit queued up notes at the last instruction of a bundle.  */
   4101 	      if (GET_MODE (insn) == QImode)
   4102 		{
   4103 		  while (queue)
   4104 		    {
   4105 		      rtx_insn *next_queue = PREV_INSN (queue);
   4106 		      SET_PREV_INSN (NEXT_INSN (insn)) = queue;
   4107 		      SET_NEXT_INSN (queue) = NEXT_INSN (insn);
   4108 		      SET_NEXT_INSN (insn) = queue;
   4109 		      SET_PREV_INSN (queue) = insn;
   4110 		      queue = next_queue;
   4111 		    }
   4112 		  in_bundle = false;
   4113 		}
   4114 	      else if (GET_MODE (insn) == SImode)
   4115 		in_bundle = true;
   4116 	    }
   4117 	  else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
   4118 	    {
   4119 	      if (in_bundle)
   4120 		{
   4121 		  rtx_insn *prev = PREV_INSN (insn);
   4122 		  SET_PREV_INSN (next) = prev;
   4123 		  SET_NEXT_INSN (prev) = next;
   4124 
   4125 		  SET_PREV_INSN (insn) = queue;
   4126 		  queue = insn;
   4127 		}
   4128 	    }
   4129 	}
   4130     }
   4131 }
   4132 
   4133 /* On some silicon revisions, functions shorter than a certain number of cycles
   4135    can cause unpredictable behavior.  Work around this by adding NOPs as
   4136    needed.  */
   4137 static void
   4138 workaround_rts_anomaly (void)
   4139 {
   4140   rtx_insn *insn, *first_insn = NULL;
   4141   int cycles = 4;
   4142 
   4143   if (! ENABLE_WA_RETS)
   4144     return;
   4145 
   4146   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
   4147     {
   4148       rtx pat;
   4149 
   4150       if (BARRIER_P (insn))
   4151 	return;
   4152 
   4153       if (NOTE_P (insn) || LABEL_P (insn))
   4154 	continue;
   4155 
   4156       if (JUMP_TABLE_DATA_P (insn))
   4157 	continue;
   4158 
   4159       if (first_insn == NULL_RTX)
   4160 	first_insn = insn;
   4161       pat = PATTERN (insn);
   4162       if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
   4163 	  || GET_CODE (pat) == ASM_INPUT
   4164 	  || asm_noperands (pat) >= 0)
   4165 	continue;
   4166 
   4167       if (CALL_P (insn))
   4168 	return;
   4169 
   4170       if (JUMP_P (insn))
   4171 	{
   4172 	  if (recog_memoized (insn) == CODE_FOR_return_internal)
   4173 	    break;
   4174 
   4175 	  /* Nothing to worry about for direct jumps.  */
   4176 	  if (!any_condjump_p (insn))
   4177 	    return;
   4178 	  if (cycles <= 1)
   4179 	    return;
   4180 	  cycles--;
   4181 	}
   4182       else if (INSN_P (insn))
   4183 	{
   4184 	  rtx pat = PATTERN (insn);
   4185 	  int this_cycles = 1;
   4186 
   4187 	  if (GET_CODE (pat) == PARALLEL)
   4188 	    {
   4189 	      if (analyze_push_multiple_operation (pat)
   4190 		  || analyze_pop_multiple_operation (pat))
   4191 		this_cycles = n_regs_to_save;
   4192 	    }
   4193 	  else
   4194 	    {
   4195 	      int icode = recog_memoized (insn);
   4196 
   4197 	      if (icode == CODE_FOR_link)
   4198 		this_cycles = 4;
   4199 	      else if (icode == CODE_FOR_unlink)
   4200 		this_cycles = 3;
   4201 	      else if (icode == CODE_FOR_mulsi3)
   4202 		this_cycles = 5;
   4203 	    }
   4204 	  if (this_cycles >= cycles)
   4205 	    return;
   4206 
   4207 	  cycles -= this_cycles;
   4208 	}
   4209     }
   4210   while (cycles > 0)
   4211     {
   4212       emit_insn_before (gen_nop (), first_insn);
   4213       cycles--;
   4214     }
   4215 }
   4216 
   4217 /* Return an insn type for INSN that can be used by the caller for anomaly
   4218    workarounds.  This differs from plain get_attr_type in that it handles
   4219    SEQUENCEs.  */
   4220 
   4221 static enum attr_type
   4222 type_for_anomaly (rtx_insn *insn)
   4223 {
   4224   rtx pat = PATTERN (insn);
   4225   if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (pat))
   4226     {
   4227       enum attr_type t;
   4228       t = get_attr_type (seq->insn (1));
   4229       if (t == TYPE_MCLD)
   4230 	return t;
   4231       t = get_attr_type (seq->insn (2));
   4232       if (t == TYPE_MCLD)
   4233 	return t;
   4234       return TYPE_MCST;
   4235     }
   4236   else
   4237     return get_attr_type (insn);
   4238 }
   4239 
   4240 /* Return true iff the address found in MEM is based on the register
   4241    NP_REG and optionally has a positive offset.  */
   4242 static bool
   4243 harmless_null_pointer_p (rtx mem, int np_reg)
   4244 {
   4245   mem = XEXP (mem, 0);
   4246   if (GET_CODE (mem) == POST_INC || GET_CODE (mem) == POST_DEC)
   4247     mem = XEXP (mem, 0);
   4248   if (REG_P (mem) && (int) REGNO (mem) == np_reg)
   4249     return true;
   4250   if (GET_CODE (mem) == PLUS
   4251       && REG_P (XEXP (mem, 0)) && (int) REGNO (XEXP (mem, 0)) == np_reg)
   4252     {
   4253       mem = XEXP (mem, 1);
   4254       if (GET_CODE (mem) == CONST_INT && INTVAL (mem) > 0)
   4255 	return true;
   4256     }
   4257   return false;
   4258 }
   4259 
   4260 /* Return nonzero if INSN contains any loads that may trap.  */
   4261 
   4262 static bool
   4263 trapping_loads_p (rtx_insn *insn, int np_reg, bool after_np_branch)
   4264 {
   4265   rtx mem = SET_SRC (single_set (insn));
   4266 
   4267   if (!after_np_branch)
   4268     np_reg = -1;
   4269   return ((np_reg == -1 || !harmless_null_pointer_p (mem, np_reg))
   4270 	  && may_trap_p (mem));
   4271 }
   4272 
   4273 /* Return INSN if it is of TYPE_MCLD.  Alternatively, if INSN is the start of
   4274    a three-insn bundle, see if one of them is a load and return that if so.
   4275    Return NULL if the insn does not contain loads.  */
   4276 static rtx_insn *
   4277 find_load (rtx_insn *insn)
   4278 {
   4279   if (!NONDEBUG_INSN_P (insn))
   4280     return NULL;
   4281   if (get_attr_type (insn) == TYPE_MCLD)
   4282     return insn;
   4283   if (GET_MODE (insn) != SImode)
   4284     return NULL;
   4285   do {
   4286     insn = NEXT_INSN (insn);
   4287     if ((GET_MODE (insn) == SImode || GET_MODE (insn) == QImode)
   4288 	&& get_attr_type (insn) == TYPE_MCLD)
   4289       return insn;
   4290   } while (GET_MODE (insn) != QImode);
   4291   return NULL;
   4292 }
   4293 
   4294 /* Determine whether PAT is an indirect call pattern.  */
   4295 static bool
   4296 indirect_call_p (rtx pat)
   4297 {
   4298   if (GET_CODE (pat) == PARALLEL)
   4299     pat = XVECEXP (pat, 0, 0);
   4300   if (GET_CODE (pat) == SET)
   4301     pat = SET_SRC (pat);
   4302   gcc_assert (GET_CODE (pat) == CALL);
   4303   pat = XEXP (pat, 0);
   4304   gcc_assert (GET_CODE (pat) == MEM);
   4305   pat = XEXP (pat, 0);
   4306 
   4307   return REG_P (pat);
   4308 }
   4309 
   4310 /* During workaround_speculation, track whether we're in the shadow of a
   4311    conditional branch that tests a P register for NULL.  If so, we can omit
   4312    emitting NOPs if we see a load from that P register, since a speculative
   4313    access at address 0 isn't a problem, and the load is executed in all other
   4314    cases anyway.
   4315    Global for communication with note_np_check_stores through note_stores.
   4316    */
   4317 int np_check_regno = -1;
   4318 bool np_after_branch = false;
   4319 
   4320 /* Subroutine of workaround_speculation, called through note_stores.  */
   4321 static void
   4322 note_np_check_stores (rtx x, const_rtx pat ATTRIBUTE_UNUSED,
   4323 		      void *data ATTRIBUTE_UNUSED)
   4324 {
   4325   if (REG_P (x) && (REGNO (x) == REG_CC || (int) REGNO (x) == np_check_regno))
   4326     np_check_regno = -1;
   4327 }
   4328 
   4329 static void
   4330 workaround_speculation (void)
   4331 {
   4332   rtx_insn *insn, *next;
   4333   rtx_insn *last_condjump = NULL;
   4334   int cycles_since_jump = INT_MAX;
   4335   int delay_added = 0;
   4336 
   4337   if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS
   4338       && ! ENABLE_WA_INDIRECT_CALLS)
   4339     return;
   4340 
   4341   /* First pass: find predicted-false branches; if something after them
   4342      needs nops, insert them or change the branch to predict true.  */
   4343   for (insn = get_insns (); insn; insn = next)
   4344     {
   4345       rtx pat;
   4346       int delay_needed = 0;
   4347 
   4348       next = find_next_insn_start (insn);
   4349 
   4350       if (NOTE_P (insn) || BARRIER_P (insn))
   4351 	continue;
   4352       if (JUMP_TABLE_DATA_P (insn))
   4353 	continue;
   4354 
   4355       if (LABEL_P (insn))
   4356 	{
   4357 	  np_check_regno = -1;
   4358 	  continue;
   4359 	}
   4360 
   4361       pat = PATTERN (insn);
   4362       if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
   4363 	continue;
   4364 
   4365       if (GET_CODE (pat) == ASM_INPUT || asm_noperands (pat) >= 0)
   4366 	{
   4367 	  np_check_regno = -1;
   4368 	  continue;
   4369 	}
   4370 
   4371       if (JUMP_P (insn))
   4372 	{
   4373 	  /* Is this a condjump based on a null pointer comparison we saw
   4374 	     earlier?  */
   4375 	  if (np_check_regno != -1
   4376 	      && recog_memoized (insn) == CODE_FOR_cbranchbi4)
   4377 	    {
   4378 	      rtx op = XEXP (SET_SRC (PATTERN (insn)), 0);
   4379 	      gcc_assert (GET_CODE (op) == EQ || GET_CODE (op) == NE);
   4380 	      if (GET_CODE (op) == NE)
   4381 		np_after_branch = true;
   4382 	    }
   4383 	  if (any_condjump_p (insn)
   4384 	      && ! cbranch_predicted_taken_p (insn))
   4385 	    {
   4386 	      last_condjump = insn;
   4387 	      delay_added = 0;
   4388 	      cycles_since_jump = 0;
   4389 	    }
   4390 	  else
   4391 	    cycles_since_jump = INT_MAX;
   4392 	}
   4393       else if (CALL_P (insn))
   4394 	{
   4395 	  np_check_regno = -1;
   4396 	  if (cycles_since_jump < INT_MAX)
   4397 	    cycles_since_jump++;
   4398 	  if (indirect_call_p (pat) && ENABLE_WA_INDIRECT_CALLS)
   4399 	    {
   4400 	      delay_needed = 3;
   4401 	    }
   4402 	}
   4403       else if (NONDEBUG_INSN_P (insn))
   4404 	{
   4405 	  rtx_insn *load_insn = find_load (insn);
   4406 	  enum attr_type type = type_for_anomaly (insn);
   4407 
   4408 	  if (cycles_since_jump < INT_MAX)
   4409 	    cycles_since_jump++;
   4410 
   4411 	  /* Detect a comparison of a P register with zero.  If we later
   4412 	     see a condjump based on it, we have found a null pointer
   4413 	     check.  */
   4414 	  if (recog_memoized (insn) == CODE_FOR_compare_eq)
   4415 	    {
   4416 	      rtx src = SET_SRC (PATTERN (insn));
   4417 	      if (REG_P (XEXP (src, 0))
   4418 		  && P_REGNO_P (REGNO (XEXP (src, 0)))
   4419 		  && XEXP (src, 1) == const0_rtx)
   4420 		{
   4421 		  np_check_regno = REGNO (XEXP (src, 0));
   4422 		  np_after_branch = false;
   4423 		}
   4424 	      else
   4425 		np_check_regno = -1;
   4426 	    }
   4427 
   4428 	  if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
   4429 	    {
   4430 	      if (trapping_loads_p (load_insn, np_check_regno,
   4431 				    np_after_branch))
   4432 		delay_needed = 4;
   4433 	    }
   4434 	  else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
   4435 	    delay_needed = 3;
   4436 
   4437 	  /* See if we need to forget about a null pointer comparison
   4438 	     we found earlier.  */
   4439 	  if (recog_memoized (insn) != CODE_FOR_compare_eq)
   4440 	    {
   4441 	      note_stores (insn, note_np_check_stores, NULL);
   4442 	      if (np_check_regno != -1)
   4443 		{
   4444 		  if (find_regno_note (insn, REG_INC, np_check_regno))
   4445 		    np_check_regno = -1;
   4446 		}
   4447 	    }
   4448 
   4449 	}
   4450 
   4451       if (delay_needed > cycles_since_jump
   4452 	  && (delay_needed - cycles_since_jump) > delay_added)
   4453 	{
   4454 	  rtx pat1;
   4455 	  int num_clobbers;
   4456 	  rtx *op = recog_data.operand;
   4457 
   4458 	  delay_needed -= cycles_since_jump;
   4459 
   4460 	  extract_insn (last_condjump);
   4461 	  if (optimize_size)
   4462 	    {
   4463 	      pat1 = gen_cbranch_predicted_taken (op[0], op[1], op[2],
   4464 						 op[3]);
   4465 	      cycles_since_jump = INT_MAX;
   4466 	    }
   4467 	  else
   4468 	    {
   4469 	      /* Do not adjust cycles_since_jump in this case, so that
   4470 		 we'll increase the number of NOPs for a subsequent insn
   4471 		 if necessary.  */
   4472 	      pat1 = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
   4473 					    GEN_INT (delay_needed));
   4474 	      delay_added = delay_needed;
   4475 	    }
   4476 	  PATTERN (last_condjump) = pat1;
   4477 	  INSN_CODE (last_condjump) = recog (pat1, insn, &num_clobbers);
   4478 	}
   4479       if (CALL_P (insn))
   4480 	{
   4481 	  cycles_since_jump = INT_MAX;
   4482 	  delay_added = 0;
   4483 	}
   4484     }
   4485 
   4486   /* Second pass: for predicted-true branches, see if anything at the
   4487      branch destination needs extra nops.  */
   4488   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
   4489     {
   4490       int cycles_since_jump;
   4491       if (JUMP_P (insn)
   4492 	  && any_condjump_p (insn)
   4493 	  && (INSN_CODE (insn) == CODE_FOR_cbranch_predicted_taken
   4494 	      || cbranch_predicted_taken_p (insn)))
   4495 	{
   4496 	  rtx_insn *target = JUMP_LABEL_AS_INSN (insn);
   4497 	  rtx_insn *label = target;
   4498 	  rtx_insn *next_tgt;
   4499 
   4500 	  cycles_since_jump = 0;
   4501 	  for (; target && cycles_since_jump < 3; target = next_tgt)
   4502 	    {
   4503 	      rtx pat;
   4504 
   4505 	      next_tgt = find_next_insn_start (target);
   4506 
   4507 	      if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
   4508 		continue;
   4509 
   4510 	      if (JUMP_TABLE_DATA_P (target))
   4511 		continue;
   4512 
   4513 	      pat = PATTERN (target);
   4514 	      if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
   4515 		  || GET_CODE (pat) == ASM_INPUT
   4516 		  || asm_noperands (pat) >= 0)
   4517 		continue;
   4518 
   4519 	      if (NONDEBUG_INSN_P (target))
   4520 		{
   4521 		  rtx_insn *load_insn = find_load (target);
   4522 		  enum attr_type type = type_for_anomaly (target);
   4523 		  int delay_needed = 0;
   4524 		  if (cycles_since_jump < INT_MAX)
   4525 		    cycles_since_jump++;
   4526 
   4527 		  if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
   4528 		    {
   4529 		      if (trapping_loads_p (load_insn, -1, false))
   4530 			delay_needed = 2;
   4531 		    }
   4532 		  else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
   4533 		    delay_needed = 2;
   4534 
   4535 		  if (delay_needed > cycles_since_jump)
   4536 		    {
   4537 		      rtx_insn *prev = prev_real_insn (label);
   4538 		      delay_needed -= cycles_since_jump;
   4539 		      if (dump_file)
   4540 			fprintf (dump_file, "Adding %d nops after %d\n",
   4541 				 delay_needed, INSN_UID (label));
   4542 		      if (JUMP_P (prev)
   4543 			  && INSN_CODE (prev) == CODE_FOR_cbranch_with_nops)
   4544 			{
   4545 			  rtx x;
   4546 			  HOST_WIDE_INT v;
   4547 
   4548 			  if (dump_file)
   4549 			    fprintf (dump_file,
   4550 				     "Reducing nops on insn %d.\n",
   4551 				     INSN_UID (prev));
   4552 			  x = PATTERN (prev);
   4553 			  x = XVECEXP (x, 0, 1);
   4554 			  v = INTVAL (XVECEXP (x, 0, 0)) - delay_needed;
   4555 			  XVECEXP (x, 0, 0) = GEN_INT (v);
   4556 			}
   4557 		      while (delay_needed-- > 0)
   4558 			emit_insn_after (gen_nop (), label);
   4559 		      break;
   4560 		    }
   4561 		}
   4562 	    }
   4563 	}
   4564     }
   4565 }
   4566 
   4567 /* Called just before the final scheduling pass.  If we need to insert NOPs
   4568    later on to work around speculative loads, insert special placeholder
   4569    insns that cause loads to be delayed for as many cycles as necessary
   4570    (and possible).  This reduces the number of NOPs we need to add.
   4571    The dummy insns we generate are later removed by bfin_gen_bundles.  */
   4572 static void
   4573 add_sched_insns_for_speculation (void)
   4574 {
   4575   rtx_insn *insn;
   4576 
   4577   if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS
   4578       && ! ENABLE_WA_INDIRECT_CALLS)
   4579     return;
   4580 
   4581   /* First pass: find predicted-false branches; if something after them
   4582      needs nops, insert them or change the branch to predict true.  */
   4583   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
   4584     {
   4585       rtx pat;
   4586 
   4587       if (NOTE_P (insn) || BARRIER_P (insn) || LABEL_P (insn))
   4588 	continue;
   4589       if (JUMP_TABLE_DATA_P (insn))
   4590 	continue;
   4591 
   4592       pat = PATTERN (insn);
   4593       if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
   4594 	  || GET_CODE (pat) == ASM_INPUT
   4595 	  || asm_noperands (pat) >= 0)
   4596 	continue;
   4597 
   4598       if (JUMP_P (insn))
   4599 	{
   4600 	  if (any_condjump_p (insn)
   4601 	      && !cbranch_predicted_taken_p (insn))
   4602 	    {
   4603 	      rtx_insn *n = next_real_insn (insn);
   4604 	      emit_insn_before (gen_stall (GEN_INT (3)), n);
   4605 	    }
   4606 	}
   4607     }
   4608 
   4609   /* Second pass: for predicted-true branches, see if anything at the
   4610      branch destination needs extra nops.  */
   4611   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
   4612     {
   4613       if (JUMP_P (insn)
   4614 	  && any_condjump_p (insn)
   4615 	  && (cbranch_predicted_taken_p (insn)))
   4616 	{
   4617 	  rtx_insn *target = JUMP_LABEL_AS_INSN (insn);
   4618 	  rtx_insn *next = next_real_insn (target);
   4619 
   4620 	  if (GET_CODE (PATTERN (next)) == UNSPEC_VOLATILE
   4621 	      && get_attr_type (next) == TYPE_STALL)
   4622 	    continue;
   4623 	  emit_insn_before (gen_stall (GEN_INT (1)), next);
   4624 	}
   4625     }
   4626 }
   4627 
   4628 /* We use the machine specific reorg pass for emitting CSYNC instructions
   4629    after conditional branches as needed.
   4630 
   4631    The Blackfin is unusual in that a code sequence like
   4632      if cc jump label
   4633      r0 = (p0)
   4634    may speculatively perform the load even if the condition isn't true.  This
   4635    happens for a branch that is predicted not taken, because the pipeline
   4636    isn't flushed or stalled, so the early stages of the following instructions,
   4637    which perform the memory reference, are allowed to execute before the
   4638    jump condition is evaluated.
   4639    Therefore, we must insert additional instructions in all places where this
   4640    could lead to incorrect behavior.  The manual recommends CSYNC, while
   4641    VDSP seems to use NOPs (even though its corresponding compiler option is
   4642    named CSYNC).
   4643 
   4644    When optimizing for speed, we emit NOPs, which seems faster than a CSYNC.
   4645    When optimizing for size, we turn the branch into a predicted taken one.
   4646    This may be slower due to mispredicts, but saves code size.  */
   4647 
   4648 static void
   4649 bfin_reorg (void)
   4650 {
   4651   /* We are freeing block_for_insn in the toplev to keep compatibility
   4652      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
   4653   compute_bb_for_insn ();
   4654 
   4655   if (flag_schedule_insns_after_reload)
   4656     {
   4657       splitting_for_sched = 1;
   4658       split_all_insns ();
   4659       splitting_for_sched = 0;
   4660 
   4661       add_sched_insns_for_speculation ();
   4662 
   4663       timevar_push (TV_SCHED2);
   4664       if (flag_selective_scheduling2
   4665 	  && !maybe_skip_selective_scheduling ())
   4666         run_selective_scheduling ();
   4667       else
   4668 	schedule_insns ();
   4669       timevar_pop (TV_SCHED2);
   4670 
   4671       /* Examine the schedule and insert nops as necessary for 64-bit parallel
   4672 	 instructions.  */
   4673       bfin_gen_bundles ();
   4674     }
   4675 
   4676   df_analyze ();
   4677 
   4678   /* Doloop optimization */
   4679   if (cfun->machine->has_hardware_loops)
   4680     bfin_reorg_loops ();
   4681 
   4682   workaround_speculation ();
   4683 
   4684   if (flag_var_tracking)
   4685     {
   4686       timevar_push (TV_VAR_TRACKING);
   4687       variable_tracking_main ();
   4688       reorder_var_tracking_notes ();
   4689       timevar_pop (TV_VAR_TRACKING);
   4690     }
   4691 
   4692   df_finish_pass (false);
   4693 
   4694   workaround_rts_anomaly ();
   4695 }
   4696 
   4697 /* Handle interrupt_handler, exception_handler and nmi_handler function
   4699    attributes; arguments as in struct attribute_spec.handler.  */
   4700 
   4701 static tree
   4702 handle_int_attribute (tree *node, tree name,
   4703 		      tree args ATTRIBUTE_UNUSED,
   4704 		      int flags ATTRIBUTE_UNUSED,
   4705 		      bool *no_add_attrs)
   4706 {
   4707   tree x = *node;
   4708   if (TREE_CODE (x) == FUNCTION_DECL)
   4709     x = TREE_TYPE (x);
   4710 
   4711   if (TREE_CODE (x) != FUNCTION_TYPE)
   4712     {
   4713       warning (OPT_Wattributes, "%qE attribute only applies to functions",
   4714 	       name);
   4715       *no_add_attrs = true;
   4716     }
   4717   else if (funkind (x) != SUBROUTINE)
   4718     error ("multiple function type attributes specified");
   4719 
   4720   return NULL_TREE;
   4721 }
   4722 
   4723 /* Return 0 if the attributes for two types are incompatible, 1 if they
   4724    are compatible, and 2 if they are nearly compatible (which causes a
   4725    warning to be generated).  */
   4726 
   4727 static int
   4728 bfin_comp_type_attributes (const_tree type1, const_tree type2)
   4729 {
   4730   e_funkind kind1, kind2;
   4731 
   4732   if (TREE_CODE (type1) != FUNCTION_TYPE)
   4733     return 1;
   4734 
   4735   kind1 = funkind (type1);
   4736   kind2 = funkind (type2);
   4737 
   4738   if (kind1 != kind2)
   4739     return 0;
   4740 
   4741   /*  Check for mismatched modifiers */
   4742   if (!lookup_attribute ("nesting", TYPE_ATTRIBUTES (type1))
   4743       != !lookup_attribute ("nesting", TYPE_ATTRIBUTES (type2)))
   4744     return 0;
   4745 
   4746   if (!lookup_attribute ("saveall", TYPE_ATTRIBUTES (type1))
   4747       != !lookup_attribute ("saveall", TYPE_ATTRIBUTES (type2)))
   4748     return 0;
   4749 
   4750   if (!lookup_attribute ("kspisusp", TYPE_ATTRIBUTES (type1))
   4751       != !lookup_attribute ("kspisusp", TYPE_ATTRIBUTES (type2)))
   4752     return 0;
   4753 
   4754   if (!lookup_attribute ("longcall", TYPE_ATTRIBUTES (type1))
   4755       != !lookup_attribute ("longcall", TYPE_ATTRIBUTES (type2)))
   4756     return 0;
   4757 
   4758   return 1;
   4759 }
   4760 
   4761 /* Handle a "longcall" or "shortcall" attribute; arguments as in
   4762    struct attribute_spec.handler.  */
   4763 
   4764 static tree
   4765 bfin_handle_longcall_attribute (tree *node, tree name,
   4766 				tree args ATTRIBUTE_UNUSED,
   4767 				int flags ATTRIBUTE_UNUSED,
   4768 				bool *no_add_attrs)
   4769 {
   4770   if (TREE_CODE (*node) != FUNCTION_TYPE
   4771       && TREE_CODE (*node) != FIELD_DECL
   4772       && TREE_CODE (*node) != TYPE_DECL)
   4773     {
   4774       warning (OPT_Wattributes, "%qE attribute only applies to functions",
   4775 	       name);
   4776       *no_add_attrs = true;
   4777     }
   4778 
   4779   if ((strcmp (IDENTIFIER_POINTER (name), "longcall") == 0
   4780        && lookup_attribute ("shortcall", TYPE_ATTRIBUTES (*node)))
   4781       || (strcmp (IDENTIFIER_POINTER (name), "shortcall") == 0
   4782 	  && lookup_attribute ("longcall", TYPE_ATTRIBUTES (*node))))
   4783     {
   4784       warning (OPT_Wattributes,
   4785 	       "cannot apply both %<longcall%> and %<shortcall%> attributes "
   4786 	       "to the same function");
   4787       *no_add_attrs = true;
   4788     }
   4789 
   4790   return NULL_TREE;
   4791 }
   4792 
   4793 /* Handle a "l1_text" attribute; arguments as in
   4794    struct attribute_spec.handler.  */
   4795 
   4796 static tree
   4797 bfin_handle_l1_text_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   4798 			       int ARG_UNUSED (flags), bool *no_add_attrs)
   4799 {
   4800   tree decl = *node;
   4801 
   4802   if (TREE_CODE (decl) != FUNCTION_DECL)
   4803     {
   4804       error ("%qE attribute only applies to functions",
   4805 	     name);
   4806       *no_add_attrs = true;
   4807     }
   4808 
   4809   /* The decl may have already been given a section attribute
   4810      from a previous declaration. Ensure they match.  */
   4811   else if (DECL_SECTION_NAME (decl) != NULL
   4812 	   && strcmp (DECL_SECTION_NAME (decl),
   4813 		      ".l1.text") != 0)
   4814     {
   4815       error ("section of %q+D conflicts with previous declaration",
   4816 	     decl);
   4817       *no_add_attrs = true;
   4818     }
   4819   else
   4820     set_decl_section_name (decl, ".l1.text");
   4821 
   4822   return NULL_TREE;
   4823 }
   4824 
   4825 /* Handle a "l1_data", "l1_data_A" or "l1_data_B" attribute;
   4826    arguments as in struct attribute_spec.handler.  */
   4827 
   4828 static tree
   4829 bfin_handle_l1_data_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   4830 			       int ARG_UNUSED (flags), bool *no_add_attrs)
   4831 {
   4832   tree decl = *node;
   4833 
   4834   if (TREE_CODE (decl) != VAR_DECL)
   4835     {
   4836       error ("%qE attribute only applies to variables",
   4837 	     name);
   4838       *no_add_attrs = true;
   4839     }
   4840   else if (current_function_decl != NULL_TREE
   4841 	   && !TREE_STATIC (decl))
   4842     {
   4843       error ("%qE attribute cannot be specified for local variables",
   4844 	     name);
   4845       *no_add_attrs = true;
   4846     }
   4847   else
   4848     {
   4849       const char *section_name;
   4850 
   4851       if (strcmp (IDENTIFIER_POINTER (name), "l1_data") == 0)
   4852 	section_name = ".l1.data";
   4853       else if (strcmp (IDENTIFIER_POINTER (name), "l1_data_A") == 0)
   4854 	section_name = ".l1.data.A";
   4855       else if (strcmp (IDENTIFIER_POINTER (name), "l1_data_B") == 0)
   4856 	section_name = ".l1.data.B";
   4857       else
   4858 	gcc_unreachable ();
   4859 
   4860       /* The decl may have already been given a section attribute
   4861 	 from a previous declaration. Ensure they match.  */
   4862       if (DECL_SECTION_NAME (decl) != NULL
   4863 	  && strcmp (DECL_SECTION_NAME (decl),
   4864 		     section_name) != 0)
   4865 	{
   4866 	  error ("section of %q+D conflicts with previous declaration",
   4867 		 decl);
   4868 	  *no_add_attrs = true;
   4869 	}
   4870       else
   4871 	set_decl_section_name (decl, section_name);
   4872     }
   4873 
   4874  return NULL_TREE;
   4875 }
   4876 
   4877 /* Handle a "l2" attribute; arguments as in struct attribute_spec.handler.  */
   4878 
   4879 static tree
   4880 bfin_handle_l2_attribute (tree *node, tree ARG_UNUSED (name),
   4881 			  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
   4882 			  bool *no_add_attrs)
   4883 {
   4884   tree decl = *node;
   4885 
   4886   if (TREE_CODE (decl) == FUNCTION_DECL)
   4887     {
   4888       if (DECL_SECTION_NAME (decl) != NULL
   4889 	  && strcmp (DECL_SECTION_NAME (decl),
   4890 		     ".l2.text") != 0)
   4891 	{
   4892 	  error ("section of %q+D conflicts with previous declaration",
   4893 		 decl);
   4894 	  *no_add_attrs = true;
   4895 	}
   4896       else
   4897 	set_decl_section_name (decl, ".l2.text");
   4898     }
   4899   else if (TREE_CODE (decl) == VAR_DECL)
   4900     {
   4901       if (DECL_SECTION_NAME (decl) != NULL
   4902 	  && strcmp (DECL_SECTION_NAME (decl),
   4903 		     ".l2.data") != 0)
   4904 	{
   4905 	  error ("section of %q+D conflicts with previous declaration",
   4906 		 decl);
   4907 	  *no_add_attrs = true;
   4908 	}
   4909       else
   4910 	set_decl_section_name (decl, ".l2.data");
   4911     }
   4912 
   4913   return NULL_TREE;
   4914 }
   4915 
   4916 /* Table of valid machine attributes.  */
   4917 static const struct attribute_spec bfin_attribute_table[] =
   4918 {
   4919   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
   4920        affects_type_identity, handler, exclude } */
   4921   { "interrupt_handler", 0, 0, false, true,  true, false,
   4922     handle_int_attribute, NULL },
   4923   { "exception_handler", 0, 0, false, true,  true, false,
   4924     handle_int_attribute, NULL },
   4925   { "nmi_handler", 0, 0, false, true,  true, false, handle_int_attribute,
   4926     NULL },
   4927   { "nesting", 0, 0, false, true,  true, false, NULL, NULL },
   4928   { "kspisusp", 0, 0, false, true,  true, false, NULL, NULL },
   4929   { "saveall", 0, 0, false, true,  true, false, NULL, NULL },
   4930   { "longcall",  0, 0, false, true,  true, false,
   4931     bfin_handle_longcall_attribute, NULL },
   4932   { "shortcall", 0, 0, false, true,  true, false,
   4933     bfin_handle_longcall_attribute, NULL },
   4934   { "l1_text", 0, 0, true, false, false, false,
   4935     bfin_handle_l1_text_attribute, NULL },
   4936   { "l1_data", 0, 0, true, false, false, false,
   4937     bfin_handle_l1_data_attribute, NULL },
   4938   { "l1_data_A", 0, 0, true, false, false, false,
   4939     bfin_handle_l1_data_attribute, NULL },
   4940   { "l1_data_B", 0, 0, true, false, false, false,
   4941     bfin_handle_l1_data_attribute, NULL },
   4942   { "l2", 0, 0, true, false, false, false, bfin_handle_l2_attribute, NULL },
   4943   { NULL, 0, 0, false, false, false, false, NULL, NULL }
   4944 };
   4945 
   4946 /* Implementation of TARGET_ASM_INTEGER.  When using FD-PIC, we need to
   4948    tell the assembler to generate pointers to function descriptors in
   4949    some cases.  */
   4950 
   4951 static bool
   4952 bfin_assemble_integer (rtx value, unsigned int size, int aligned_p)
   4953 {
   4954   if (TARGET_FDPIC && size == UNITS_PER_WORD)
   4955     {
   4956       if (GET_CODE (value) == SYMBOL_REF
   4957 	  && SYMBOL_REF_FUNCTION_P (value))
   4958 	{
   4959 	  fputs ("\t.picptr\tfuncdesc(", asm_out_file);
   4960 	  output_addr_const (asm_out_file, value);
   4961 	  fputs (")\n", asm_out_file);
   4962 	  return true;
   4963 	}
   4964       if (!aligned_p)
   4965 	{
   4966 	  /* We've set the unaligned SI op to NULL, so we always have to
   4967 	     handle the unaligned case here.  */
   4968 	  assemble_integer_with_op ("\t.4byte\t", value);
   4969 	  return true;
   4970 	}
   4971     }
   4972   return default_assemble_integer (value, size, aligned_p);
   4973 }
   4974 
   4975 /* Output the assembler code for a thunk function.  THUNK_DECL is the
   4977    declaration for the thunk function itself, FUNCTION is the decl for
   4978    the target function.  DELTA is an immediate constant offset to be
   4979    added to THIS.  If VCALL_OFFSET is nonzero, the word at
   4980    *(*this + vcall_offset) should be added to THIS.  */
   4981 
   4982 static void
   4983 bfin_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
   4984 		      tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
   4985 		      HOST_WIDE_INT vcall_offset, tree function)
   4986 {
   4987   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
   4988   rtx xops[3];
   4989   /* The this parameter is passed as the first argument.  */
   4990   rtx this_rtx = gen_rtx_REG (Pmode, REG_R0);
   4991 
   4992   assemble_start_function (thunk, fnname);
   4993   /* Adjust the this parameter by a fixed constant.  */
   4994   if (delta)
   4995     {
   4996       xops[1] = this_rtx;
   4997       if (delta >= -64 && delta <= 63)
   4998 	{
   4999 	  xops[0] = GEN_INT (delta);
   5000 	  output_asm_insn ("%1 += %0;", xops);
   5001 	}
   5002       else if (delta >= -128 && delta < -64)
   5003 	{
   5004 	  xops[0] = GEN_INT (delta + 64);
   5005 	  output_asm_insn ("%1 += -64; %1 += %0;", xops);
   5006 	}
   5007       else if (delta > 63 && delta <= 126)
   5008 	{
   5009 	  xops[0] = GEN_INT (delta - 63);
   5010 	  output_asm_insn ("%1 += 63; %1 += %0;", xops);
   5011 	}
   5012       else
   5013 	{
   5014 	  xops[0] = GEN_INT (delta);
   5015 	  output_asm_insn ("r3.l = %h0; r3.h = %d0; %1 = %1 + r3;", xops);
   5016 	}
   5017     }
   5018 
   5019   /* Adjust the this parameter by a value stored in the vtable.  */
   5020   if (vcall_offset)
   5021     {
   5022       rtx p2tmp = gen_rtx_REG (Pmode, REG_P2);
   5023       rtx tmp = gen_rtx_REG (Pmode, REG_R3);
   5024 
   5025       xops[1] = tmp;
   5026       xops[2] = p2tmp;
   5027       output_asm_insn ("%2 = r0; %2 = [%2];", xops);
   5028 
   5029       /* Adjust the this parameter.  */
   5030       xops[0] = gen_rtx_MEM (Pmode, plus_constant (Pmode, p2tmp,
   5031 						   vcall_offset));
   5032       if (!memory_operand (xops[0], Pmode))
   5033 	{
   5034 	  rtx tmp2 = gen_rtx_REG (Pmode, REG_P1);
   5035 	  xops[0] = GEN_INT (vcall_offset);
   5036 	  xops[1] = tmp2;
   5037 	  output_asm_insn ("%h1 = %h0; %d1 = %d0; %2 = %2 + %1", xops);
   5038 	  xops[0] = gen_rtx_MEM (Pmode, p2tmp);
   5039 	}
   5040       xops[2] = this_rtx;
   5041       output_asm_insn ("%1 = %0; %2 = %2 + %1;", xops);
   5042     }
   5043 
   5044   xops[0] = XEXP (DECL_RTL (function), 0);
   5045   if (1 || !flag_pic || (*targetm.binds_local_p) (function))
   5046     output_asm_insn ("jump.l\t%P0", xops);
   5047   assemble_end_function (thunk, fnname);
   5048 }
   5049 
   5050 /* Codes for all the Blackfin builtins.  */
   5052 enum bfin_builtins
   5053 {
   5054   BFIN_BUILTIN_CSYNC,
   5055   BFIN_BUILTIN_SSYNC,
   5056   BFIN_BUILTIN_ONES,
   5057   BFIN_BUILTIN_COMPOSE_2X16,
   5058   BFIN_BUILTIN_EXTRACTLO,
   5059   BFIN_BUILTIN_EXTRACTHI,
   5060 
   5061   BFIN_BUILTIN_SSADD_2X16,
   5062   BFIN_BUILTIN_SSSUB_2X16,
   5063   BFIN_BUILTIN_SSADDSUB_2X16,
   5064   BFIN_BUILTIN_SSSUBADD_2X16,
   5065   BFIN_BUILTIN_MULT_2X16,
   5066   BFIN_BUILTIN_MULTR_2X16,
   5067   BFIN_BUILTIN_NEG_2X16,
   5068   BFIN_BUILTIN_ABS_2X16,
   5069   BFIN_BUILTIN_MIN_2X16,
   5070   BFIN_BUILTIN_MAX_2X16,
   5071 
   5072   BFIN_BUILTIN_SSADD_1X16,
   5073   BFIN_BUILTIN_SSSUB_1X16,
   5074   BFIN_BUILTIN_MULT_1X16,
   5075   BFIN_BUILTIN_MULTR_1X16,
   5076   BFIN_BUILTIN_NORM_1X16,
   5077   BFIN_BUILTIN_NEG_1X16,
   5078   BFIN_BUILTIN_ABS_1X16,
   5079   BFIN_BUILTIN_MIN_1X16,
   5080   BFIN_BUILTIN_MAX_1X16,
   5081 
   5082   BFIN_BUILTIN_SUM_2X16,
   5083   BFIN_BUILTIN_DIFFHL_2X16,
   5084   BFIN_BUILTIN_DIFFLH_2X16,
   5085 
   5086   BFIN_BUILTIN_SSADD_1X32,
   5087   BFIN_BUILTIN_SSSUB_1X32,
   5088   BFIN_BUILTIN_NORM_1X32,
   5089   BFIN_BUILTIN_ROUND_1X32,
   5090   BFIN_BUILTIN_NEG_1X32,
   5091   BFIN_BUILTIN_ABS_1X32,
   5092   BFIN_BUILTIN_MIN_1X32,
   5093   BFIN_BUILTIN_MAX_1X32,
   5094   BFIN_BUILTIN_MULT_1X32,
   5095   BFIN_BUILTIN_MULT_1X32X32,
   5096   BFIN_BUILTIN_MULT_1X32X32NS,
   5097 
   5098   BFIN_BUILTIN_MULHISILL,
   5099   BFIN_BUILTIN_MULHISILH,
   5100   BFIN_BUILTIN_MULHISIHL,
   5101   BFIN_BUILTIN_MULHISIHH,
   5102 
   5103   BFIN_BUILTIN_LSHIFT_1X16,
   5104   BFIN_BUILTIN_LSHIFT_2X16,
   5105   BFIN_BUILTIN_SSASHIFT_1X16,
   5106   BFIN_BUILTIN_SSASHIFT_2X16,
   5107   BFIN_BUILTIN_SSASHIFT_1X32,
   5108 
   5109   BFIN_BUILTIN_CPLX_MUL_16,
   5110   BFIN_BUILTIN_CPLX_MAC_16,
   5111   BFIN_BUILTIN_CPLX_MSU_16,
   5112 
   5113   BFIN_BUILTIN_CPLX_MUL_16_S40,
   5114   BFIN_BUILTIN_CPLX_MAC_16_S40,
   5115   BFIN_BUILTIN_CPLX_MSU_16_S40,
   5116 
   5117   BFIN_BUILTIN_CPLX_SQU,
   5118 
   5119   BFIN_BUILTIN_LOADBYTES,
   5120 
   5121   BFIN_BUILTIN_MAX
   5122 };
   5123 
   5124 #define def_builtin(NAME, TYPE, CODE)					\
   5125 do {									\
   5126   add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,		\
   5127 		       NULL, NULL_TREE);				\
   5128 } while (0)
   5129 
   5130 /* Set up all builtin functions for this target.  */
   5131 static void
   5132 bfin_init_builtins (void)
   5133 {
   5134   tree V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
   5135   tree void_ftype_void
   5136     = build_function_type_list (void_type_node, NULL_TREE);
   5137   tree short_ftype_short
   5138     = build_function_type_list (short_integer_type_node, short_integer_type_node,
   5139 				NULL_TREE);
   5140   tree short_ftype_int_int
   5141     = build_function_type_list (short_integer_type_node, integer_type_node,
   5142 				integer_type_node, NULL_TREE);
   5143   tree int_ftype_int_int
   5144     = build_function_type_list (integer_type_node, integer_type_node,
   5145 				integer_type_node, NULL_TREE);
   5146   tree int_ftype_int
   5147     = build_function_type_list (integer_type_node, integer_type_node,
   5148 				NULL_TREE);
   5149   tree short_ftype_int
   5150     = build_function_type_list (short_integer_type_node, integer_type_node,
   5151 				NULL_TREE);
   5152   tree int_ftype_v2hi_v2hi
   5153     = build_function_type_list (integer_type_node, V2HI_type_node,
   5154 				V2HI_type_node, NULL_TREE);
   5155   tree v2hi_ftype_v2hi_v2hi
   5156     = build_function_type_list (V2HI_type_node, V2HI_type_node,
   5157 				V2HI_type_node, NULL_TREE);
   5158   tree v2hi_ftype_v2hi_v2hi_v2hi
   5159     = build_function_type_list (V2HI_type_node, V2HI_type_node,
   5160 				V2HI_type_node, V2HI_type_node, NULL_TREE);
   5161   tree v2hi_ftype_int_int
   5162     = build_function_type_list (V2HI_type_node, integer_type_node,
   5163 				integer_type_node, NULL_TREE);
   5164   tree v2hi_ftype_v2hi_int
   5165     = build_function_type_list (V2HI_type_node, V2HI_type_node,
   5166 				integer_type_node, NULL_TREE);
   5167   tree int_ftype_short_short
   5168     = build_function_type_list (integer_type_node, short_integer_type_node,
   5169 				short_integer_type_node, NULL_TREE);
   5170   tree v2hi_ftype_v2hi
   5171     = build_function_type_list (V2HI_type_node, V2HI_type_node, NULL_TREE);
   5172   tree short_ftype_v2hi
   5173     = build_function_type_list (short_integer_type_node, V2HI_type_node,
   5174 				NULL_TREE);
   5175   tree int_ftype_pint
   5176     = build_function_type_list (integer_type_node,
   5177 				build_pointer_type (integer_type_node),
   5178 				NULL_TREE);
   5179 
   5180   /* Add the remaining MMX insns with somewhat more complicated types.  */
   5181   def_builtin ("__builtin_bfin_csync", void_ftype_void, BFIN_BUILTIN_CSYNC);
   5182   def_builtin ("__builtin_bfin_ssync", void_ftype_void, BFIN_BUILTIN_SSYNC);
   5183 
   5184   def_builtin ("__builtin_bfin_ones", short_ftype_int, BFIN_BUILTIN_ONES);
   5185 
   5186   def_builtin ("__builtin_bfin_compose_2x16", v2hi_ftype_int_int,
   5187 	       BFIN_BUILTIN_COMPOSE_2X16);
   5188   def_builtin ("__builtin_bfin_extract_hi", short_ftype_v2hi,
   5189 	       BFIN_BUILTIN_EXTRACTHI);
   5190   def_builtin ("__builtin_bfin_extract_lo", short_ftype_v2hi,
   5191 	       BFIN_BUILTIN_EXTRACTLO);
   5192 
   5193   def_builtin ("__builtin_bfin_min_fr2x16", v2hi_ftype_v2hi_v2hi,
   5194 	       BFIN_BUILTIN_MIN_2X16);
   5195   def_builtin ("__builtin_bfin_max_fr2x16", v2hi_ftype_v2hi_v2hi,
   5196 	       BFIN_BUILTIN_MAX_2X16);
   5197 
   5198   def_builtin ("__builtin_bfin_add_fr2x16", v2hi_ftype_v2hi_v2hi,
   5199 	       BFIN_BUILTIN_SSADD_2X16);
   5200   def_builtin ("__builtin_bfin_sub_fr2x16", v2hi_ftype_v2hi_v2hi,
   5201 	       BFIN_BUILTIN_SSSUB_2X16);
   5202   def_builtin ("__builtin_bfin_dspaddsubsat", v2hi_ftype_v2hi_v2hi,
   5203 	       BFIN_BUILTIN_SSADDSUB_2X16);
   5204   def_builtin ("__builtin_bfin_dspsubaddsat", v2hi_ftype_v2hi_v2hi,
   5205 	       BFIN_BUILTIN_SSSUBADD_2X16);
   5206   def_builtin ("__builtin_bfin_mult_fr2x16", v2hi_ftype_v2hi_v2hi,
   5207 	       BFIN_BUILTIN_MULT_2X16);
   5208   def_builtin ("__builtin_bfin_multr_fr2x16", v2hi_ftype_v2hi_v2hi,
   5209 	       BFIN_BUILTIN_MULTR_2X16);
   5210   def_builtin ("__builtin_bfin_negate_fr2x16", v2hi_ftype_v2hi,
   5211 	       BFIN_BUILTIN_NEG_2X16);
   5212   def_builtin ("__builtin_bfin_abs_fr2x16", v2hi_ftype_v2hi,
   5213 	       BFIN_BUILTIN_ABS_2X16);
   5214 
   5215   def_builtin ("__builtin_bfin_min_fr1x16", short_ftype_int_int,
   5216 	       BFIN_BUILTIN_MIN_1X16);
   5217   def_builtin ("__builtin_bfin_max_fr1x16", short_ftype_int_int,
   5218 	       BFIN_BUILTIN_MAX_1X16);
   5219 
   5220   def_builtin ("__builtin_bfin_add_fr1x16", short_ftype_int_int,
   5221 	       BFIN_BUILTIN_SSADD_1X16);
   5222   def_builtin ("__builtin_bfin_sub_fr1x16", short_ftype_int_int,
   5223 	       BFIN_BUILTIN_SSSUB_1X16);
   5224   def_builtin ("__builtin_bfin_mult_fr1x16", short_ftype_int_int,
   5225 	       BFIN_BUILTIN_MULT_1X16);
   5226   def_builtin ("__builtin_bfin_multr_fr1x16", short_ftype_int_int,
   5227 	       BFIN_BUILTIN_MULTR_1X16);
   5228   def_builtin ("__builtin_bfin_negate_fr1x16", short_ftype_short,
   5229 	       BFIN_BUILTIN_NEG_1X16);
   5230   def_builtin ("__builtin_bfin_abs_fr1x16", short_ftype_short,
   5231 	       BFIN_BUILTIN_ABS_1X16);
   5232   def_builtin ("__builtin_bfin_norm_fr1x16", short_ftype_int,
   5233 	       BFIN_BUILTIN_NORM_1X16);
   5234 
   5235   def_builtin ("__builtin_bfin_sum_fr2x16", short_ftype_v2hi,
   5236 	       BFIN_BUILTIN_SUM_2X16);
   5237   def_builtin ("__builtin_bfin_diff_hl_fr2x16", short_ftype_v2hi,
   5238 	       BFIN_BUILTIN_DIFFHL_2X16);
   5239   def_builtin ("__builtin_bfin_diff_lh_fr2x16", short_ftype_v2hi,
   5240 	       BFIN_BUILTIN_DIFFLH_2X16);
   5241 
   5242   def_builtin ("__builtin_bfin_mulhisill", int_ftype_v2hi_v2hi,
   5243 	       BFIN_BUILTIN_MULHISILL);
   5244   def_builtin ("__builtin_bfin_mulhisihl", int_ftype_v2hi_v2hi,
   5245 	       BFIN_BUILTIN_MULHISIHL);
   5246   def_builtin ("__builtin_bfin_mulhisilh", int_ftype_v2hi_v2hi,
   5247 	       BFIN_BUILTIN_MULHISILH);
   5248   def_builtin ("__builtin_bfin_mulhisihh", int_ftype_v2hi_v2hi,
   5249 	       BFIN_BUILTIN_MULHISIHH);
   5250 
   5251   def_builtin ("__builtin_bfin_min_fr1x32", int_ftype_int_int,
   5252 	       BFIN_BUILTIN_MIN_1X32);
   5253   def_builtin ("__builtin_bfin_max_fr1x32", int_ftype_int_int,
   5254 	       BFIN_BUILTIN_MAX_1X32);
   5255 
   5256   def_builtin ("__builtin_bfin_add_fr1x32", int_ftype_int_int,
   5257 	       BFIN_BUILTIN_SSADD_1X32);
   5258   def_builtin ("__builtin_bfin_sub_fr1x32", int_ftype_int_int,
   5259 	       BFIN_BUILTIN_SSSUB_1X32);
   5260   def_builtin ("__builtin_bfin_negate_fr1x32", int_ftype_int,
   5261 	       BFIN_BUILTIN_NEG_1X32);
   5262   def_builtin ("__builtin_bfin_abs_fr1x32", int_ftype_int,
   5263 	       BFIN_BUILTIN_ABS_1X32);
   5264   def_builtin ("__builtin_bfin_norm_fr1x32", short_ftype_int,
   5265 	       BFIN_BUILTIN_NORM_1X32);
   5266   def_builtin ("__builtin_bfin_round_fr1x32", short_ftype_int,
   5267 	       BFIN_BUILTIN_ROUND_1X32);
   5268   def_builtin ("__builtin_bfin_mult_fr1x32", int_ftype_short_short,
   5269 	       BFIN_BUILTIN_MULT_1X32);
   5270   def_builtin ("__builtin_bfin_mult_fr1x32x32", int_ftype_int_int,
   5271 	       BFIN_BUILTIN_MULT_1X32X32);
   5272   def_builtin ("__builtin_bfin_mult_fr1x32x32NS", int_ftype_int_int,
   5273 	       BFIN_BUILTIN_MULT_1X32X32NS);
   5274 
   5275   /* Shifts.  */
   5276   def_builtin ("__builtin_bfin_shl_fr1x16", short_ftype_int_int,
   5277 	       BFIN_BUILTIN_SSASHIFT_1X16);
   5278   def_builtin ("__builtin_bfin_shl_fr2x16", v2hi_ftype_v2hi_int,
   5279 	       BFIN_BUILTIN_SSASHIFT_2X16);
   5280   def_builtin ("__builtin_bfin_lshl_fr1x16", short_ftype_int_int,
   5281 	       BFIN_BUILTIN_LSHIFT_1X16);
   5282   def_builtin ("__builtin_bfin_lshl_fr2x16", v2hi_ftype_v2hi_int,
   5283 	       BFIN_BUILTIN_LSHIFT_2X16);
   5284   def_builtin ("__builtin_bfin_shl_fr1x32", int_ftype_int_int,
   5285 	       BFIN_BUILTIN_SSASHIFT_1X32);
   5286 
   5287   /* Complex numbers.  */
   5288   def_builtin ("__builtin_bfin_cmplx_add", v2hi_ftype_v2hi_v2hi,
   5289 	       BFIN_BUILTIN_SSADD_2X16);
   5290   def_builtin ("__builtin_bfin_cmplx_sub", v2hi_ftype_v2hi_v2hi,
   5291 	       BFIN_BUILTIN_SSSUB_2X16);
   5292   def_builtin ("__builtin_bfin_cmplx_mul", v2hi_ftype_v2hi_v2hi,
   5293 	       BFIN_BUILTIN_CPLX_MUL_16);
   5294   def_builtin ("__builtin_bfin_cmplx_mac", v2hi_ftype_v2hi_v2hi_v2hi,
   5295 	       BFIN_BUILTIN_CPLX_MAC_16);
   5296   def_builtin ("__builtin_bfin_cmplx_msu", v2hi_ftype_v2hi_v2hi_v2hi,
   5297 	       BFIN_BUILTIN_CPLX_MSU_16);
   5298   def_builtin ("__builtin_bfin_cmplx_mul_s40", v2hi_ftype_v2hi_v2hi,
   5299 	       BFIN_BUILTIN_CPLX_MUL_16_S40);
   5300   def_builtin ("__builtin_bfin_cmplx_mac_s40", v2hi_ftype_v2hi_v2hi_v2hi,
   5301 	       BFIN_BUILTIN_CPLX_MAC_16_S40);
   5302   def_builtin ("__builtin_bfin_cmplx_msu_s40", v2hi_ftype_v2hi_v2hi_v2hi,
   5303 	       BFIN_BUILTIN_CPLX_MSU_16_S40);
   5304   def_builtin ("__builtin_bfin_csqu_fr16", v2hi_ftype_v2hi,
   5305 	       BFIN_BUILTIN_CPLX_SQU);
   5306 
   5307   /* "Unaligned" load.  */
   5308   def_builtin ("__builtin_bfin_loadbytes", int_ftype_pint,
   5309 	       BFIN_BUILTIN_LOADBYTES);
   5310 
   5311 }
   5312 
   5313 
   5314 struct builtin_description
   5315 {
   5316   const enum insn_code icode;
   5317   const char *const name;
   5318   const enum bfin_builtins code;
   5319   int macflag;
   5320 };
   5321 
   5322 static const struct builtin_description bdesc_2arg[] =
   5323 {
   5324   { CODE_FOR_composev2hi, "__builtin_bfin_compose_2x16", BFIN_BUILTIN_COMPOSE_2X16, -1 },
   5325 
   5326   { CODE_FOR_ssashiftv2hi3, "__builtin_bfin_shl_fr2x16", BFIN_BUILTIN_SSASHIFT_2X16, -1 },
   5327   { CODE_FOR_ssashifthi3, "__builtin_bfin_shl_fr1x16", BFIN_BUILTIN_SSASHIFT_1X16, -1 },
   5328   { CODE_FOR_lshiftv2hi3, "__builtin_bfin_lshl_fr2x16", BFIN_BUILTIN_LSHIFT_2X16, -1 },
   5329   { CODE_FOR_lshifthi3, "__builtin_bfin_lshl_fr1x16", BFIN_BUILTIN_LSHIFT_1X16, -1 },
   5330   { CODE_FOR_ssashiftsi3, "__builtin_bfin_shl_fr1x32", BFIN_BUILTIN_SSASHIFT_1X32, -1 },
   5331 
   5332   { CODE_FOR_sminhi3, "__builtin_bfin_min_fr1x16", BFIN_BUILTIN_MIN_1X16, -1 },
   5333   { CODE_FOR_smaxhi3, "__builtin_bfin_max_fr1x16", BFIN_BUILTIN_MAX_1X16, -1 },
   5334   { CODE_FOR_ssaddhi3, "__builtin_bfin_add_fr1x16", BFIN_BUILTIN_SSADD_1X16, -1 },
   5335   { CODE_FOR_sssubhi3, "__builtin_bfin_sub_fr1x16", BFIN_BUILTIN_SSSUB_1X16, -1 },
   5336 
   5337   { CODE_FOR_sminsi3, "__builtin_bfin_min_fr1x32", BFIN_BUILTIN_MIN_1X32, -1 },
   5338   { CODE_FOR_smaxsi3, "__builtin_bfin_max_fr1x32", BFIN_BUILTIN_MAX_1X32, -1 },
   5339   { CODE_FOR_ssaddsi3, "__builtin_bfin_add_fr1x32", BFIN_BUILTIN_SSADD_1X32, -1 },
   5340   { CODE_FOR_sssubsi3, "__builtin_bfin_sub_fr1x32", BFIN_BUILTIN_SSSUB_1X32, -1 },
   5341 
   5342   { CODE_FOR_sminv2hi3, "__builtin_bfin_min_fr2x16", BFIN_BUILTIN_MIN_2X16, -1 },
   5343   { CODE_FOR_smaxv2hi3, "__builtin_bfin_max_fr2x16", BFIN_BUILTIN_MAX_2X16, -1 },
   5344   { CODE_FOR_ssaddv2hi3, "__builtin_bfin_add_fr2x16", BFIN_BUILTIN_SSADD_2X16, -1 },
   5345   { CODE_FOR_sssubv2hi3, "__builtin_bfin_sub_fr2x16", BFIN_BUILTIN_SSSUB_2X16, -1 },
   5346   { CODE_FOR_ssaddsubv2hi3, "__builtin_bfin_dspaddsubsat", BFIN_BUILTIN_SSADDSUB_2X16, -1 },
   5347   { CODE_FOR_sssubaddv2hi3, "__builtin_bfin_dspsubaddsat", BFIN_BUILTIN_SSSUBADD_2X16, -1 },
   5348 
   5349   { CODE_FOR_flag_mulhisi, "__builtin_bfin_mult_fr1x32", BFIN_BUILTIN_MULT_1X32, MACFLAG_NONE },
   5350   { CODE_FOR_flag_mulhi, "__builtin_bfin_mult_fr1x16", BFIN_BUILTIN_MULT_1X16, MACFLAG_T },
   5351   { CODE_FOR_flag_mulhi, "__builtin_bfin_multr_fr1x16", BFIN_BUILTIN_MULTR_1X16, MACFLAG_NONE },
   5352   { CODE_FOR_flag_mulv2hi, "__builtin_bfin_mult_fr2x16", BFIN_BUILTIN_MULT_2X16, MACFLAG_T },
   5353   { CODE_FOR_flag_mulv2hi, "__builtin_bfin_multr_fr2x16", BFIN_BUILTIN_MULTR_2X16, MACFLAG_NONE },
   5354 
   5355   { CODE_FOR_mulhisi_ll, "__builtin_bfin_mulhisill", BFIN_BUILTIN_MULHISILL, -1 },
   5356   { CODE_FOR_mulhisi_lh, "__builtin_bfin_mulhisilh", BFIN_BUILTIN_MULHISILH, -1 },
   5357   { CODE_FOR_mulhisi_hl, "__builtin_bfin_mulhisihl", BFIN_BUILTIN_MULHISIHL, -1 },
   5358   { CODE_FOR_mulhisi_hh, "__builtin_bfin_mulhisihh", BFIN_BUILTIN_MULHISIHH, -1 }
   5359 
   5360 };
   5361 
   5362 static const struct builtin_description bdesc_1arg[] =
   5363 {
   5364   { CODE_FOR_loadbytes, "__builtin_bfin_loadbytes", BFIN_BUILTIN_LOADBYTES, 0 },
   5365 
   5366   { CODE_FOR_ones, "__builtin_bfin_ones", BFIN_BUILTIN_ONES, 0 },
   5367 
   5368   { CODE_FOR_clrsbhi2, "__builtin_bfin_norm_fr1x16", BFIN_BUILTIN_NORM_1X16, 0 },
   5369   { CODE_FOR_ssneghi2, "__builtin_bfin_negate_fr1x16", BFIN_BUILTIN_NEG_1X16, 0 },
   5370   { CODE_FOR_abshi2, "__builtin_bfin_abs_fr1x16", BFIN_BUILTIN_ABS_1X16, 0 },
   5371 
   5372   { CODE_FOR_clrsbsi2, "__builtin_bfin_norm_fr1x32", BFIN_BUILTIN_NORM_1X32, 0 },
   5373   { CODE_FOR_ssroundsi2, "__builtin_bfin_round_fr1x32", BFIN_BUILTIN_ROUND_1X32, 0 },
   5374   { CODE_FOR_ssnegsi2, "__builtin_bfin_negate_fr1x32", BFIN_BUILTIN_NEG_1X32, 0 },
   5375   { CODE_FOR_ssabssi2, "__builtin_bfin_abs_fr1x32", BFIN_BUILTIN_ABS_1X32, 0 },
   5376 
   5377   { CODE_FOR_movv2hi_hi_low, "__builtin_bfin_extract_lo", BFIN_BUILTIN_EXTRACTLO, 0 },
   5378   { CODE_FOR_movv2hi_hi_high, "__builtin_bfin_extract_hi", BFIN_BUILTIN_EXTRACTHI, 0 },
   5379   { CODE_FOR_ssnegv2hi2, "__builtin_bfin_negate_fr2x16", BFIN_BUILTIN_NEG_2X16, 0 },
   5380   { CODE_FOR_ssabsv2hi2, "__builtin_bfin_abs_fr2x16", BFIN_BUILTIN_ABS_2X16, 0 }
   5381 };
   5382 
   5383 /* Errors in the source file can cause expand_expr to return const0_rtx
   5384    where we expect a vector.  To avoid crashing, use one of the vector
   5385    clear instructions.  */
   5386 static rtx
   5387 safe_vector_operand (rtx x, machine_mode mode)
   5388 {
   5389   if (x != const0_rtx)
   5390     return x;
   5391   x = gen_reg_rtx (SImode);
   5392 
   5393   emit_insn (gen_movsi (x, CONST0_RTX (SImode)));
   5394   return gen_lowpart (mode, x);
   5395 }
   5396 
   5397 /* Subroutine of bfin_expand_builtin to take care of binop insns.  MACFLAG is -1
   5398    if this is a normal binary op, or one of the MACFLAG_xxx constants.  */
   5399 
   5400 static rtx
   5401 bfin_expand_binop_builtin (enum insn_code icode, tree exp, rtx target,
   5402 			   int macflag)
   5403 {
   5404   rtx pat;
   5405   tree arg0 = CALL_EXPR_ARG (exp, 0);
   5406   tree arg1 = CALL_EXPR_ARG (exp, 1);
   5407   rtx op0 = expand_normal (arg0);
   5408   rtx op1 = expand_normal (arg1);
   5409   machine_mode op0mode = GET_MODE (op0);
   5410   machine_mode op1mode = GET_MODE (op1);
   5411   machine_mode tmode = insn_data[icode].operand[0].mode;
   5412   machine_mode mode0 = insn_data[icode].operand[1].mode;
   5413   machine_mode mode1 = insn_data[icode].operand[2].mode;
   5414 
   5415   if (VECTOR_MODE_P (mode0))
   5416     op0 = safe_vector_operand (op0, mode0);
   5417   if (VECTOR_MODE_P (mode1))
   5418     op1 = safe_vector_operand (op1, mode1);
   5419 
   5420   if (! target
   5421       || GET_MODE (target) != tmode
   5422       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
   5423     target = gen_reg_rtx (tmode);
   5424 
   5425   if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
   5426     {
   5427       op0mode = HImode;
   5428       op0 = gen_lowpart (HImode, op0);
   5429     }
   5430   if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
   5431     {
   5432       op1mode = HImode;
   5433       op1 = gen_lowpart (HImode, op1);
   5434     }
   5435   /* In case the insn wants input operands in modes different from
   5436      the result, abort.  */
   5437   gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
   5438 	      && (op1mode == mode1 || op1mode == VOIDmode));
   5439 
   5440   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
   5441     op0 = copy_to_mode_reg (mode0, op0);
   5442   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
   5443     op1 = copy_to_mode_reg (mode1, op1);
   5444 
   5445   if (macflag == -1)
   5446     pat = GEN_FCN (icode) (target, op0, op1);
   5447   else
   5448     pat = GEN_FCN (icode) (target, op0, op1, GEN_INT (macflag));
   5449   if (! pat)
   5450     return 0;
   5451 
   5452   emit_insn (pat);
   5453   return target;
   5454 }
   5455 
   5456 /* Subroutine of bfin_expand_builtin to take care of unop insns.  */
   5457 
   5458 static rtx
   5459 bfin_expand_unop_builtin (enum insn_code icode, tree exp,
   5460 			  rtx target)
   5461 {
   5462   rtx pat;
   5463   tree arg0 = CALL_EXPR_ARG (exp, 0);
   5464   rtx op0 = expand_normal (arg0);
   5465   machine_mode op0mode = GET_MODE (op0);
   5466   machine_mode tmode = insn_data[icode].operand[0].mode;
   5467   machine_mode mode0 = insn_data[icode].operand[1].mode;
   5468 
   5469   if (! target
   5470       || GET_MODE (target) != tmode
   5471       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
   5472     target = gen_reg_rtx (tmode);
   5473 
   5474   if (VECTOR_MODE_P (mode0))
   5475     op0 = safe_vector_operand (op0, mode0);
   5476 
   5477   if (op0mode == SImode && mode0 == HImode)
   5478     {
   5479       op0mode = HImode;
   5480       op0 = gen_lowpart (HImode, op0);
   5481     }
   5482   gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
   5483 
   5484   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
   5485     op0 = copy_to_mode_reg (mode0, op0);
   5486 
   5487   pat = GEN_FCN (icode) (target, op0);
   5488   if (! pat)
   5489     return 0;
   5490   emit_insn (pat);
   5491   return target;
   5492 }
   5493 
   5494 /* Expand an expression EXP that calls a built-in function,
   5495    with result going to TARGET if that's convenient
   5496    (and in mode MODE if that's convenient).
   5497    SUBTARGET may be used as the target for computing one of EXP's operands.
   5498    IGNORE is nonzero if the value is to be ignored.  */
   5499 
   5500 static rtx
   5501 bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
   5502 		     rtx subtarget ATTRIBUTE_UNUSED,
   5503 		     machine_mode mode ATTRIBUTE_UNUSED,
   5504 		     int ignore ATTRIBUTE_UNUSED)
   5505 {
   5506   size_t i;
   5507   enum insn_code icode;
   5508   const struct builtin_description *d;
   5509   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   5510   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   5511   tree arg0, arg1, arg2;
   5512   rtx op0, op1, op2, accvec, pat, tmp1, tmp2, a0reg, a1reg;
   5513   machine_mode tmode, mode0;
   5514 
   5515   switch (fcode)
   5516     {
   5517     case BFIN_BUILTIN_CSYNC:
   5518       emit_insn (gen_csync ());
   5519       return 0;
   5520     case BFIN_BUILTIN_SSYNC:
   5521       emit_insn (gen_ssync ());
   5522       return 0;
   5523 
   5524     case BFIN_BUILTIN_DIFFHL_2X16:
   5525     case BFIN_BUILTIN_DIFFLH_2X16:
   5526     case BFIN_BUILTIN_SUM_2X16:
   5527       arg0 = CALL_EXPR_ARG (exp, 0);
   5528       op0 = expand_normal (arg0);
   5529       icode = (fcode == BFIN_BUILTIN_DIFFHL_2X16 ? CODE_FOR_subhilov2hi3
   5530 	       : fcode == BFIN_BUILTIN_DIFFLH_2X16 ? CODE_FOR_sublohiv2hi3
   5531 	       : CODE_FOR_ssaddhilov2hi3);
   5532       tmode = insn_data[icode].operand[0].mode;
   5533       mode0 = insn_data[icode].operand[1].mode;
   5534 
   5535       if (! target
   5536 	  || GET_MODE (target) != tmode
   5537 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
   5538 	target = gen_reg_rtx (tmode);
   5539 
   5540       if (VECTOR_MODE_P (mode0))
   5541 	op0 = safe_vector_operand (op0, mode0);
   5542 
   5543       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
   5544 	op0 = copy_to_mode_reg (mode0, op0);
   5545 
   5546       pat = GEN_FCN (icode) (target, op0, op0);
   5547       if (! pat)
   5548 	return 0;
   5549       emit_insn (pat);
   5550       return target;
   5551 
   5552     case BFIN_BUILTIN_MULT_1X32X32:
   5553     case BFIN_BUILTIN_MULT_1X32X32NS:
   5554       arg0 = CALL_EXPR_ARG (exp, 0);
   5555       arg1 = CALL_EXPR_ARG (exp, 1);
   5556       op0 = expand_normal (arg0);
   5557       op1 = expand_normal (arg1);
   5558       if (! target
   5559 	  || !register_operand (target, SImode))
   5560 	target = gen_reg_rtx (SImode);
   5561       if (! register_operand (op0, SImode))
   5562 	op0 = copy_to_mode_reg (SImode, op0);
   5563       if (! register_operand (op1, SImode))
   5564 	op1 = copy_to_mode_reg (SImode, op1);
   5565 
   5566       a1reg = gen_rtx_REG (PDImode, REG_A1);
   5567       a0reg = gen_rtx_REG (PDImode, REG_A0);
   5568       tmp1 = gen_lowpart (V2HImode, op0);
   5569       tmp2 = gen_lowpart (V2HImode, op1);
   5570       emit_insn (gen_flag_macinit1hi (a1reg,
   5571 				      gen_lowpart (HImode, op0),
   5572 				      gen_lowpart (HImode, op1),
   5573 				      GEN_INT (MACFLAG_FU)));
   5574       emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
   5575 
   5576       if (fcode == BFIN_BUILTIN_MULT_1X32X32)
   5577 	emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg, tmp1, tmp2,
   5578 						       const1_rtx, const1_rtx,
   5579 						       const1_rtx, const0_rtx, a1reg,
   5580 						       const0_rtx, GEN_INT (MACFLAG_NONE),
   5581 						       GEN_INT (MACFLAG_M)));
   5582       else
   5583 	{
   5584 	  /* For saturating multiplication, there's exactly one special case
   5585 	     to be handled: multiplying the smallest negative value with
   5586 	     itself.  Due to shift correction in fractional multiplies, this
   5587 	     can overflow.  Iff this happens, OP2 will contain 1, which, when
   5588 	     added in 32 bits to the smallest negative, wraps to the largest
   5589 	     positive, which is the result we want.  */
   5590 	  op2 = gen_reg_rtx (V2HImode);
   5591 	  emit_insn (gen_packv2hi (op2, tmp1, tmp2, const0_rtx, const0_rtx));
   5592 	  emit_insn (gen_movsibi (gen_rtx_REG (BImode, REG_CC),
   5593 				  gen_lowpart (SImode, op2)));
   5594 	  emit_insn (gen_flag_mul_macv2hi_parts_acconly_andcc0 (a0reg, a1reg, tmp1, tmp2,
   5595 								const1_rtx, const1_rtx,
   5596 								const1_rtx, const0_rtx, a1reg,
   5597 								const0_rtx, GEN_INT (MACFLAG_NONE),
   5598 								GEN_INT (MACFLAG_M)));
   5599 	  op2 = gen_reg_rtx (SImode);
   5600 	  emit_insn (gen_movbisi (op2, gen_rtx_REG (BImode, REG_CC)));
   5601 	}
   5602       emit_insn (gen_flag_machi_parts_acconly (a1reg, tmp2, tmp1,
   5603 					       const1_rtx, const0_rtx,
   5604 					       a1reg, const0_rtx, GEN_INT (MACFLAG_M)));
   5605       emit_insn (gen_ashrpdi3 (a1reg, a1reg, GEN_INT (15)));
   5606       emit_insn (gen_sum_of_accumulators (target, a0reg, a0reg, a1reg));
   5607       if (fcode == BFIN_BUILTIN_MULT_1X32X32NS)
   5608 	emit_insn (gen_addsi3 (target, target, op2));
   5609       return target;
   5610 
   5611     case BFIN_BUILTIN_CPLX_MUL_16:
   5612     case BFIN_BUILTIN_CPLX_MUL_16_S40:
   5613       arg0 = CALL_EXPR_ARG (exp, 0);
   5614       arg1 = CALL_EXPR_ARG (exp, 1);
   5615       op0 = expand_normal (arg0);
   5616       op1 = expand_normal (arg1);
   5617       accvec = gen_reg_rtx (V2PDImode);
   5618       icode = CODE_FOR_flag_macv2hi_parts;
   5619       tmode = insn_data[icode].operand[0].mode;
   5620 
   5621       if (! target
   5622 	  || GET_MODE (target) != V2HImode
   5623 	  || ! (*insn_data[icode].operand[0].predicate) (target, V2HImode))
   5624 	target = gen_reg_rtx (tmode);
   5625       if (! register_operand (op0, GET_MODE (op0)))
   5626 	op0 = copy_to_mode_reg (GET_MODE (op0), op0);
   5627       if (! register_operand (op1, GET_MODE (op1)))
   5628 	op1 = copy_to_mode_reg (GET_MODE (op1), op1);
   5629 
   5630       if (fcode == BFIN_BUILTIN_CPLX_MUL_16)
   5631 	emit_insn (gen_flag_macinit1v2hi_parts (accvec, op0, op1, const0_rtx,
   5632 						const0_rtx, const0_rtx,
   5633 						const1_rtx, GEN_INT (MACFLAG_W32)));
   5634       else
   5635 	emit_insn (gen_flag_macinit1v2hi_parts (accvec, op0, op1, const0_rtx,
   5636 						const0_rtx, const0_rtx,
   5637 						const1_rtx, GEN_INT (MACFLAG_NONE)));
   5638       emit_insn (gen_flag_macv2hi_parts (target, op0, op1, const1_rtx,
   5639 					 const1_rtx, const1_rtx,
   5640 					 const0_rtx, accvec, const1_rtx, const0_rtx,
   5641 					 GEN_INT (MACFLAG_NONE), accvec));
   5642 
   5643       return target;
   5644 
   5645     case BFIN_BUILTIN_CPLX_MAC_16:
   5646     case BFIN_BUILTIN_CPLX_MSU_16:
   5647     case BFIN_BUILTIN_CPLX_MAC_16_S40:
   5648     case BFIN_BUILTIN_CPLX_MSU_16_S40:
   5649       arg0 = CALL_EXPR_ARG (exp, 0);
   5650       arg1 = CALL_EXPR_ARG (exp, 1);
   5651       arg2 = CALL_EXPR_ARG (exp, 2);
   5652       op0 = expand_normal (arg0);
   5653       op1 = expand_normal (arg1);
   5654       op2 = expand_normal (arg2);
   5655       accvec = gen_reg_rtx (V2PDImode);
   5656       icode = CODE_FOR_flag_macv2hi_parts;
   5657       tmode = insn_data[icode].operand[0].mode;
   5658 
   5659       if (! target
   5660 	  || GET_MODE (target) != V2HImode
   5661 	  || ! (*insn_data[icode].operand[0].predicate) (target, V2HImode))
   5662 	target = gen_reg_rtx (tmode);
   5663       if (! register_operand (op1, GET_MODE (op1)))
   5664 	op1 = copy_to_mode_reg (GET_MODE (op1), op1);
   5665       if (! register_operand (op2, GET_MODE (op2)))
   5666 	op2 = copy_to_mode_reg (GET_MODE (op2), op2);
   5667 
   5668       tmp1 = gen_reg_rtx (SImode);
   5669       tmp2 = gen_reg_rtx (SImode);
   5670       emit_insn (gen_ashlsi3 (tmp1, gen_lowpart (SImode, op0), GEN_INT (16)));
   5671       emit_move_insn (tmp2, gen_lowpart (SImode, op0));
   5672       emit_insn (gen_movstricthi_1 (gen_lowpart (HImode, tmp2), const0_rtx));
   5673       emit_insn (gen_load_accumulator_pair (accvec, tmp1, tmp2));
   5674       if (fcode == BFIN_BUILTIN_CPLX_MAC_16
   5675 	  || fcode == BFIN_BUILTIN_CPLX_MSU_16)
   5676 	emit_insn (gen_flag_macv2hi_parts_acconly (accvec, op1, op2, const0_rtx,
   5677 						   const0_rtx, const0_rtx,
   5678 						   const1_rtx, accvec, const0_rtx,
   5679 						   const0_rtx,
   5680 						   GEN_INT (MACFLAG_W32)));
   5681       else
   5682 	emit_insn (gen_flag_macv2hi_parts_acconly (accvec, op1, op2, const0_rtx,
   5683 						   const0_rtx, const0_rtx,
   5684 						   const1_rtx, accvec, const0_rtx,
   5685 						   const0_rtx,
   5686 						   GEN_INT (MACFLAG_NONE)));
   5687       if (fcode == BFIN_BUILTIN_CPLX_MAC_16
   5688 	  || fcode == BFIN_BUILTIN_CPLX_MAC_16_S40)
   5689 	{
   5690 	  tmp1 = const1_rtx;
   5691 	  tmp2 = const0_rtx;
   5692 	}
   5693       else
   5694 	{
   5695 	  tmp1 = const0_rtx;
   5696 	  tmp2 = const1_rtx;
   5697 	}
   5698       emit_insn (gen_flag_macv2hi_parts (target, op1, op2, const1_rtx,
   5699 					 const1_rtx, const1_rtx,
   5700 					 const0_rtx, accvec, tmp1, tmp2,
   5701 					 GEN_INT (MACFLAG_NONE), accvec));
   5702 
   5703       return target;
   5704 
   5705     case BFIN_BUILTIN_CPLX_SQU:
   5706       arg0 = CALL_EXPR_ARG (exp, 0);
   5707       op0 = expand_normal (arg0);
   5708       accvec = gen_reg_rtx (V2PDImode);
   5709       icode = CODE_FOR_flag_mulv2hi;
   5710       tmp1 = gen_reg_rtx (V2HImode);
   5711       tmp2 = gen_reg_rtx (V2HImode);
   5712 
   5713       if (! target
   5714 	  || GET_MODE (target) != V2HImode
   5715 	  || ! (*insn_data[icode].operand[0].predicate) (target, V2HImode))
   5716 	target = gen_reg_rtx (V2HImode);
   5717       if (! register_operand (op0, GET_MODE (op0)))
   5718 	op0 = copy_to_mode_reg (GET_MODE (op0), op0);
   5719 
   5720       emit_insn (gen_flag_mulv2hi (tmp1, op0, op0, GEN_INT (MACFLAG_NONE)));
   5721 
   5722       emit_insn (gen_flag_mulhi_parts (gen_lowpart (HImode, tmp2), op0, op0,
   5723 				       const0_rtx, const1_rtx,
   5724 				       GEN_INT (MACFLAG_NONE)));
   5725 
   5726       emit_insn (gen_ssaddhi3_high_parts (target, tmp2, tmp2, tmp2, const0_rtx,
   5727 					  const0_rtx));
   5728       emit_insn (gen_sssubhi3_low_parts (target, target, tmp1, tmp1,
   5729 					 const0_rtx, const1_rtx));
   5730 
   5731       return target;
   5732 
   5733     default:
   5734       break;
   5735     }
   5736 
   5737   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
   5738     if (d->code == fcode)
   5739       return bfin_expand_binop_builtin (d->icode, exp, target,
   5740 					d->macflag);
   5741 
   5742   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
   5743     if (d->code == fcode)
   5744       return bfin_expand_unop_builtin (d->icode, exp, target);
   5745 
   5746   gcc_unreachable ();
   5747 }
   5748 
   5749 static void
   5750 bfin_conditional_register_usage (void)
   5751 {
   5752   /* initialize condition code flag register rtx */
   5753   bfin_cc_rtx = gen_rtx_REG (BImode, REG_CC);
   5754   bfin_rets_rtx = gen_rtx_REG (Pmode, REG_RETS);
   5755   if (TARGET_FDPIC)
   5756     call_used_regs[FDPIC_REGNO] = 1;
   5757   if (!TARGET_FDPIC && flag_pic)
   5758     {
   5759       fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
   5760       call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
   5761     }
   5762 }
   5763 
   5764 #undef TARGET_INIT_BUILTINS
   5766 #define TARGET_INIT_BUILTINS bfin_init_builtins
   5767 
   5768 #undef TARGET_EXPAND_BUILTIN
   5769 #define TARGET_EXPAND_BUILTIN bfin_expand_builtin
   5770 
   5771 #undef TARGET_ASM_GLOBALIZE_LABEL
   5772 #define TARGET_ASM_GLOBALIZE_LABEL bfin_globalize_label
   5773 
   5774 #undef TARGET_ASM_FILE_START
   5775 #define TARGET_ASM_FILE_START output_file_start
   5776 
   5777 #undef TARGET_ATTRIBUTE_TABLE
   5778 #define TARGET_ATTRIBUTE_TABLE bfin_attribute_table
   5779 
   5780 #undef TARGET_COMP_TYPE_ATTRIBUTES
   5781 #define TARGET_COMP_TYPE_ATTRIBUTES bfin_comp_type_attributes
   5782 
   5783 #undef TARGET_RTX_COSTS
   5784 #define TARGET_RTX_COSTS bfin_rtx_costs
   5785 
   5786 #undef  TARGET_ADDRESS_COST
   5787 #define TARGET_ADDRESS_COST bfin_address_cost
   5788 
   5789 #undef TARGET_REGISTER_MOVE_COST
   5790 #define TARGET_REGISTER_MOVE_COST bfin_register_move_cost
   5791 
   5792 #undef TARGET_MEMORY_MOVE_COST
   5793 #define TARGET_MEMORY_MOVE_COST bfin_memory_move_cost
   5794 
   5795 #undef  TARGET_ASM_INTEGER
   5796 #define TARGET_ASM_INTEGER bfin_assemble_integer
   5797 
   5798 #undef TARGET_MACHINE_DEPENDENT_REORG
   5799 #define TARGET_MACHINE_DEPENDENT_REORG bfin_reorg
   5800 
   5801 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   5802 #define TARGET_FUNCTION_OK_FOR_SIBCALL bfin_function_ok_for_sibcall
   5803 
   5804 #undef TARGET_ASM_OUTPUT_MI_THUNK
   5805 #define TARGET_ASM_OUTPUT_MI_THUNK bfin_output_mi_thunk
   5806 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
   5807 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
   5808 
   5809 #undef TARGET_SCHED_ADJUST_COST
   5810 #define TARGET_SCHED_ADJUST_COST bfin_adjust_cost
   5811 
   5812 #undef TARGET_SCHED_ISSUE_RATE
   5813 #define TARGET_SCHED_ISSUE_RATE bfin_issue_rate
   5814 
   5815 #undef TARGET_PROMOTE_FUNCTION_MODE
   5816 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
   5817 
   5818 #undef TARGET_ARG_PARTIAL_BYTES
   5819 #define TARGET_ARG_PARTIAL_BYTES bfin_arg_partial_bytes
   5820 
   5821 #undef TARGET_FUNCTION_ARG
   5822 #define TARGET_FUNCTION_ARG bfin_function_arg
   5823 
   5824 #undef TARGET_FUNCTION_ARG_ADVANCE
   5825 #define TARGET_FUNCTION_ARG_ADVANCE bfin_function_arg_advance
   5826 
   5827 #undef TARGET_PASS_BY_REFERENCE
   5828 #define TARGET_PASS_BY_REFERENCE bfin_pass_by_reference
   5829 
   5830 #undef TARGET_SETUP_INCOMING_VARARGS
   5831 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
   5832 
   5833 #undef TARGET_STRUCT_VALUE_RTX
   5834 #define TARGET_STRUCT_VALUE_RTX bfin_struct_value_rtx
   5835 
   5836 #undef TARGET_VECTOR_MODE_SUPPORTED_P
   5837 #define TARGET_VECTOR_MODE_SUPPORTED_P bfin_vector_mode_supported_p
   5838 
   5839 #undef TARGET_OPTION_OVERRIDE
   5840 #define TARGET_OPTION_OVERRIDE bfin_option_override
   5841 
   5842 #undef TARGET_SECONDARY_RELOAD
   5843 #define TARGET_SECONDARY_RELOAD bfin_secondary_reload
   5844 
   5845 #undef TARGET_CLASS_LIKELY_SPILLED_P
   5846 #define TARGET_CLASS_LIKELY_SPILLED_P bfin_class_likely_spilled_p
   5847 
   5848 #undef TARGET_DELEGITIMIZE_ADDRESS
   5849 #define TARGET_DELEGITIMIZE_ADDRESS bfin_delegitimize_address
   5850 
   5851 #undef TARGET_LEGITIMATE_CONSTANT_P
   5852 #define TARGET_LEGITIMATE_CONSTANT_P bfin_legitimate_constant_p
   5853 
   5854 #undef TARGET_CANNOT_FORCE_CONST_MEM
   5855 #define TARGET_CANNOT_FORCE_CONST_MEM bfin_cannot_force_const_mem
   5856 
   5857 #undef TARGET_RETURN_IN_MEMORY
   5858 #define TARGET_RETURN_IN_MEMORY bfin_return_in_memory
   5859 
   5860 #undef TARGET_LRA_P
   5861 #define TARGET_LRA_P hook_bool_void_false
   5862 
   5863 #undef TARGET_LEGITIMATE_ADDRESS_P
   5864 #define TARGET_LEGITIMATE_ADDRESS_P	bfin_legitimate_address_p
   5865 
   5866 #undef TARGET_FRAME_POINTER_REQUIRED
   5867 #define TARGET_FRAME_POINTER_REQUIRED bfin_frame_pointer_required
   5868 
   5869 #undef TARGET_CAN_ELIMINATE
   5870 #define TARGET_CAN_ELIMINATE bfin_can_eliminate
   5871 
   5872 #undef TARGET_CONDITIONAL_REGISTER_USAGE
   5873 #define TARGET_CONDITIONAL_REGISTER_USAGE bfin_conditional_register_usage
   5874 
   5875 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
   5876 #define TARGET_ASM_TRAMPOLINE_TEMPLATE bfin_asm_trampoline_template
   5877 #undef TARGET_TRAMPOLINE_INIT
   5878 #define TARGET_TRAMPOLINE_INIT bfin_trampoline_init
   5879 
   5880 #undef TARGET_EXTRA_LIVE_ON_ENTRY
   5881 #define TARGET_EXTRA_LIVE_ON_ENTRY bfin_extra_live_on_entry
   5882 
   5883 /* Passes after sched2 can break the helpful TImode annotations that
   5884    haifa-sched puts on every insn.  Just do scheduling in reorg.  */
   5885 #undef TARGET_DELAY_SCHED2
   5886 #define TARGET_DELAY_SCHED2 true
   5887 
   5888 /* Variable tracking should be run after all optimizations which
   5889    change order of insns.  It also needs a valid CFG.  */
   5890 #undef TARGET_DELAY_VARTRACK
   5891 #define TARGET_DELAY_VARTRACK true
   5892 
   5893 #undef TARGET_CAN_USE_DOLOOP_P
   5894 #define TARGET_CAN_USE_DOLOOP_P bfin_can_use_doloop_p
   5895 
   5896 #undef TARGET_HARD_REGNO_NREGS
   5897 #define TARGET_HARD_REGNO_NREGS bfin_hard_regno_nregs
   5898 #undef TARGET_HARD_REGNO_MODE_OK
   5899 #define TARGET_HARD_REGNO_MODE_OK bfin_hard_regno_mode_ok
   5900 
   5901 #undef TARGET_MODES_TIEABLE_P
   5902 #define TARGET_MODES_TIEABLE_P bfin_modes_tieable_p
   5903 
   5904 #undef TARGET_CONSTANT_ALIGNMENT
   5905 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
   5906 
   5907 struct gcc_target targetm = TARGET_INITIALIZER;
   5908