OSDN Git Service

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