common.opt (-Wattributes): New.
[platform/upstream/gcc.git] / gcc / config / bfin / bfin.c
1 /* The Blackfin code generation auxiliary output file.
2    Copyright (C) 2005  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, 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, 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 "conditions.h"
32 #include "insn-flags.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "tree.h"
36 #include "flags.h"
37 #include "except.h"
38 #include "function.h"
39 #include "input.h"
40 #include "target.h"
41 #include "target-def.h"
42 #include "expr.h"
43 #include "toplev.h"
44 #include "recog.h"
45 #include "ggc.h"
46 #include "integrate.h"
47 #include "bfin-protos.h"
48 #include "tm-preds.h"
49 #include "gt-bfin.h"
50
51 /* Test and compare insns in bfin.md store the information needed to
52    generate branch and scc insns here.  */
53 rtx bfin_compare_op0, bfin_compare_op1;
54
55 /* RTX for condition code flag register and RETS register */
56 extern GTY(()) rtx bfin_cc_rtx;
57 extern GTY(()) rtx bfin_rets_rtx;
58 rtx bfin_cc_rtx, bfin_rets_rtx;
59
60 int max_arg_registers = 0;
61
62 /* Arrays used when emitting register names.  */
63 const char *short_reg_names[]  =  SHORT_REGISTER_NAMES;
64 const char *high_reg_names[]   =  HIGH_REGISTER_NAMES;
65 const char *dregs_pair_names[] =  DREGS_PAIR_NAMES;
66 const char *byte_reg_names[]   =  BYTE_REGISTER_NAMES;
67
68 static int arg_regs[] = FUNCTION_ARG_REGISTERS;
69
70 /* The value passed to -mshared-library-id=.  */
71 static int bfin_library_id;
72 /* Nonzero if -mshared-library-id was given.  */
73 static int bfin_lib_id_given;
74
75 static void
76 bfin_globalize_label (FILE *stream, const char *name)
77 {
78   fputs (".global ", stream);
79   assemble_name (stream, name);
80   fputc (';',stream);
81   fputc ('\n',stream);
82 }
83
84 static void 
85 output_file_start (void) 
86 {
87   FILE *file = asm_out_file;
88   int i;
89
90   fprintf (file, ".file \"%s\";\n", input_filename);
91   
92   for (i = 0; arg_regs[i] >= 0; i++)
93     ;
94   max_arg_registers = i;        /* how many arg reg used  */
95 }
96
97 /* Called early in the compilation to conditionally modify
98    fixed_regs/call_used_regs.  */
99
100 void 
101 conditional_register_usage (void)
102 {
103   /* initialize condition code flag register rtx */
104   bfin_cc_rtx = gen_rtx_REG (BImode, REG_CC);
105   bfin_rets_rtx = gen_rtx_REG (Pmode, REG_RETS);
106 }
107
108 /* Examine machine-dependent attributes of function type FUNTYPE and return its
109    type.  See the definition of E_FUNKIND.  */
110
111 static e_funkind funkind (tree funtype)
112 {
113   tree attrs = TYPE_ATTRIBUTES (funtype);
114   if (lookup_attribute ("interrupt_handler", attrs))
115     return INTERRUPT_HANDLER;
116   else if (lookup_attribute ("exception_handler", attrs))
117     return EXCPT_HANDLER;
118   else if (lookup_attribute ("nmi_handler", attrs))
119     return NMI_HANDLER;
120   else
121     return SUBROUTINE;
122 }
123 \f
124 /* Stack frame layout. */
125
126 /* Compute the number of DREGS to save with a push_multiple operation.
127    This could include registers that aren't modified in the function,
128    since push_multiple only takes a range of registers.  */
129
130 static int
131 n_dregs_to_save (void)
132 {
133   unsigned i;
134
135   for (i = REG_R0; i <= REG_R7; i++)
136     {
137       if (regs_ever_live[i] && ! call_used_regs[i])
138         return REG_R7 - i + 1;
139
140       if (current_function_calls_eh_return)
141         {
142           unsigned j;
143           for (j = 0; ; j++)
144             {
145               unsigned test = EH_RETURN_DATA_REGNO (j);
146               if (test == INVALID_REGNUM)
147                 break;
148               if (test == i)
149                 return REG_R7 - i + 1;
150             }
151         }
152
153     }
154   return 0;
155 }
156
157 /* Like n_dregs_to_save, but compute number of PREGS to save.  */
158
159 static int
160 n_pregs_to_save (void)
161 {
162   unsigned i;
163
164   for (i = REG_P0; i <= REG_P5; i++)
165     if ((regs_ever_live[i] && ! call_used_regs[i])
166         || (i == PIC_OFFSET_TABLE_REGNUM
167             && (current_function_uses_pic_offset_table
168                 || (TARGET_ID_SHARED_LIBRARY && ! current_function_is_leaf))))
169       return REG_P5 - i + 1;
170   return 0;
171 }
172
173 /* Determine if we are going to save the frame pointer in the prologue.  */
174
175 static bool
176 must_save_fp_p (void)
177 {
178   return (frame_pointer_needed || regs_ever_live[REG_FP]);
179 }
180
181 static bool
182 stack_frame_needed_p (void)
183 {
184   /* EH return puts a new return address into the frame using an
185      address relative to the frame pointer.  */
186   if (current_function_calls_eh_return)
187     return true;
188   return frame_pointer_needed;
189 }
190
191 /* Emit code to save registers in the prologue.  SAVEALL is nonzero if we
192    must save all registers; this is used for interrupt handlers.
193    SPREG contains (reg:SI REG_SP).  */
194
195 static void
196 expand_prologue_reg_save (rtx spreg, int saveall)
197 {
198   int ndregs = saveall ? 8 : n_dregs_to_save ();
199   int npregs = saveall ? 6 : n_pregs_to_save ();
200   int dregno = REG_R7 + 1 - ndregs;
201   int pregno = REG_P5 + 1 - npregs;
202   int total = ndregs + npregs;
203   int i;
204   rtx pat, insn, val;
205
206   if (total == 0)
207     return;
208
209   val = GEN_INT (-total * 4);
210   pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total + 2));
211   XVECEXP (pat, 0, 0) = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, val),
212                                         UNSPEC_PUSH_MULTIPLE);
213   XVECEXP (pat, 0, total + 1) = gen_rtx_SET (VOIDmode, spreg,
214                                              gen_rtx_PLUS (Pmode, spreg,
215                                                            val));
216   RTX_FRAME_RELATED_P (XVECEXP (pat, 0, total + 1)) = 1;
217   for (i = 0; i < total; i++)
218     {
219       rtx memref = gen_rtx_MEM (word_mode,
220                                 gen_rtx_PLUS (Pmode, spreg,
221                                               GEN_INT (- i * 4 - 4)));
222       rtx subpat;
223       if (ndregs > 0)
224         {
225           subpat = gen_rtx_SET (VOIDmode, memref, gen_rtx_REG (word_mode,
226                                                                dregno++));
227           ndregs--;
228         }
229       else
230         {
231           subpat = gen_rtx_SET (VOIDmode, memref, gen_rtx_REG (word_mode,
232                                                                pregno++));
233           npregs++;
234         }
235       XVECEXP (pat, 0, i + 1) = subpat;
236       RTX_FRAME_RELATED_P (subpat) = 1;
237     }
238   insn = emit_insn (pat);
239   RTX_FRAME_RELATED_P (insn) = 1;
240 }
241
242 /* Emit code to restore registers in the epilogue.  SAVEALL is nonzero if we
243    must save all registers; this is used for interrupt handlers.
244    SPREG contains (reg:SI REG_SP).  */
245
246 static void
247 expand_epilogue_reg_restore (rtx spreg, int saveall)
248 {
249   int ndregs = saveall ? 8 : n_dregs_to_save ();
250   int npregs = saveall ? 6 : n_pregs_to_save ();
251   int total = ndregs + npregs;
252   int i, regno;
253   rtx pat, insn;
254
255   if (total == 0)
256     return;
257
258   pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total + 1));
259   XVECEXP (pat, 0, 0) = gen_rtx_SET (VOIDmode, spreg,
260                                      gen_rtx_PLUS (Pmode, spreg,
261                                                    GEN_INT (total * 4)));
262
263   if (npregs > 0)
264     regno = REG_P5 + 1;
265   else
266     regno = REG_R7 + 1;
267
268   for (i = 0; i < total; i++)
269     {
270       rtx addr = (i > 0
271                   ? gen_rtx_PLUS (Pmode, spreg, GEN_INT (i * 4))
272                   : spreg);
273       rtx memref = gen_rtx_MEM (word_mode, addr);
274
275       regno--;
276       XVECEXP (pat, 0, i + 1)
277         = gen_rtx_SET (VOIDmode, gen_rtx_REG (word_mode, regno), memref);
278
279       if (npregs > 0)
280         {
281           if (--npregs == 0)
282             regno = REG_R7 + 1;
283         }
284     }
285
286   insn = emit_insn (pat);
287   RTX_FRAME_RELATED_P (insn) = 1;
288 }
289
290 /* Perform any needed actions needed for a function that is receiving a
291    variable number of arguments.
292
293    CUM is as above.
294
295    MODE and TYPE are the mode and type of the current parameter.
296
297    PRETEND_SIZE is a variable that should be set to the amount of stack
298    that must be pushed by the prolog to pretend that our caller pushed
299    it.
300
301    Normally, this macro will push all remaining incoming registers on the
302    stack and set PRETEND_SIZE to the length of the registers pushed.  
303
304    Blackfin specific :
305    - VDSP C compiler manual (our ABI) says that a variable args function
306      should save the R0, R1 and R2 registers in the stack.
307    - The caller will always leave space on the stack for the
308      arguments that are passed in registers, so we dont have
309      to leave any extra space.
310    - now, the vastart pointer can access all arguments from the stack.  */
311
312 static void
313 setup_incoming_varargs (CUMULATIVE_ARGS *cum,
314                         enum machine_mode mode ATTRIBUTE_UNUSED,
315                         tree type ATTRIBUTE_UNUSED, int *pretend_size,
316                         int no_rtl)
317 {
318   rtx mem;
319   int i;
320
321   if (no_rtl)
322     return;
323
324   /* The move for named arguments will be generated automatically by the
325      compiler.  We need to generate the move rtx for the unnamed arguments
326      if they are in the first 3 words.  We assume at least 1 named argument
327      exists, so we never generate [ARGP] = R0 here.  */
328
329   for (i = cum->words + 1; i < max_arg_registers; i++)
330     {
331       mem = gen_rtx_MEM (Pmode,
332                          plus_constant (arg_pointer_rtx, (i * UNITS_PER_WORD)));
333       emit_move_insn (mem, gen_rtx_REG (Pmode, i));
334     }
335
336   *pretend_size = 0;
337 }
338
339 /* Value should be nonzero if functions must have frame pointers.
340    Zero means the frame pointer need not be set up (and parms may
341    be accessed via the stack pointer) in functions that seem suitable.  */
342
343 int
344 bfin_frame_pointer_required (void) 
345 {
346   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
347
348   if (fkind != SUBROUTINE)
349     return 1;
350
351   /* We turn on on -fomit-frame-pointer if -momit-leaf-frame-pointer is used,
352      so we have to override it for non-leaf functions.  */
353   if (TARGET_OMIT_LEAF_FRAME_POINTER && ! current_function_is_leaf)
354     return 1;
355
356   return 0;
357 }
358
359 /* Return the number of registers pushed during the prologue.  */
360
361 static int
362 n_regs_saved_by_prologue (void)
363 {
364   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
365   int n = n_dregs_to_save () + n_pregs_to_save ();
366
367   if (stack_frame_needed_p ())
368     /* We use a LINK instruction in this case.  */
369     n += 2;
370   else
371     {
372       if (must_save_fp_p ())
373         n++;
374       if (! current_function_is_leaf)
375         n++;
376     }
377
378   if (fkind != SUBROUTINE)
379     {
380       tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
381       tree all = lookup_attribute ("saveall", attrs);
382       int i;
383
384       /* Increment once for ASTAT.  */
385       n++;
386
387       /* RETE/X/N.  */
388       if (lookup_attribute ("nesting", attrs))
389         n++;
390
391       for (i = REG_P7 + 1; i < REG_CC; i++)
392         if (all 
393             || regs_ever_live[i]
394             || (!leaf_function_p () && call_used_regs[i]))
395           n += i == REG_A0 || i == REG_A1 ? 2 : 1;
396     }
397   return n;
398 }
399
400 /* Return the offset between two registers, one to be eliminated, and the other
401    its replacement, at the start of a routine.  */
402
403 HOST_WIDE_INT
404 bfin_initial_elimination_offset (int from, int to)
405 {
406   HOST_WIDE_INT offset = 0;
407
408   if (from == ARG_POINTER_REGNUM)
409     offset = n_regs_saved_by_prologue () * 4;
410
411   if (to == STACK_POINTER_REGNUM)
412     {
413       if (current_function_outgoing_args_size >= FIXED_STACK_AREA)
414         offset += current_function_outgoing_args_size;
415       else if (current_function_outgoing_args_size)
416         offset += FIXED_STACK_AREA;
417
418       offset += get_frame_size ();
419     }
420
421   return offset;
422 }
423
424 /* Emit code to load a constant CONSTANT into register REG; setting
425    RTX_FRAME_RELATED_P on all insns we generate.  Make sure that the insns
426    we generate need not be split.  */
427
428 static void
429 frame_related_constant_load (rtx reg, HOST_WIDE_INT constant)
430 {
431   rtx insn;
432   rtx cst = GEN_INT (constant);
433
434   if (constant >= -32768 && constant < 65536)
435     insn = emit_move_insn (reg, cst);
436   else
437     {
438       /* We don't call split_load_immediate here, since dwarf2out.c can get
439          confused about some of the more clever sequences it can generate.  */
440       insn = emit_insn (gen_movsi_high (reg, cst));
441       RTX_FRAME_RELATED_P (insn) = 1;
442       insn = emit_insn (gen_movsi_low (reg, reg, cst));
443     }
444   RTX_FRAME_RELATED_P (insn) = 1;
445 }
446
447 /* Generate efficient code to add a value to the frame pointer.  We
448    can use P1 as a scratch register.  Set RTX_FRAME_RELATED_P on the
449    generated insns if FRAME is nonzero.  */
450
451 static void
452 add_to_sp (rtx spreg, HOST_WIDE_INT value, int frame)
453 {
454   if (value == 0)
455     return;
456
457   /* Choose whether to use a sequence using a temporary register, or
458      a sequence with multiple adds.  We can add a signed 7 bit value
459      in one instruction.  */
460   if (value > 120 || value < -120)
461     {
462       rtx tmpreg = gen_rtx_REG (SImode, REG_P1);
463       rtx insn;
464
465       if (frame)
466         frame_related_constant_load (tmpreg, value);
467       else
468         {
469           insn = emit_move_insn (tmpreg, GEN_INT (value));
470           if (frame)
471             RTX_FRAME_RELATED_P (insn) = 1;
472         }
473
474       insn = emit_insn (gen_addsi3 (spreg, spreg, tmpreg));
475       if (frame)
476         RTX_FRAME_RELATED_P (insn) = 1;
477     }
478   else
479     do
480       {
481         int size = value;
482         rtx insn;
483
484         if (size > 60)
485           size = 60;
486         else if (size < -60)
487           /* We could use -62, but that would leave the stack unaligned, so
488              it's no good.  */
489           size = -60;
490
491         insn = emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (size)));
492         if (frame)
493           RTX_FRAME_RELATED_P (insn) = 1;
494         value -= size;
495       }
496     while (value != 0);
497 }
498
499 /* Generate a LINK insn for a frame sized FRAME_SIZE.  If this constant
500    is too large, generate a sequence of insns that has the same effect.
501    SPREG contains (reg:SI REG_SP).  */
502
503 static void
504 emit_link_insn (rtx spreg, HOST_WIDE_INT frame_size)
505 {
506   HOST_WIDE_INT link_size = frame_size;
507   rtx insn;
508   int i;
509
510   if (link_size > 262140)
511     link_size = 262140;
512
513   /* Use a LINK insn with as big a constant as possible, then subtract
514      any remaining size from the SP.  */
515   insn = emit_insn (gen_link (GEN_INT (-8 - link_size)));
516   RTX_FRAME_RELATED_P (insn) = 1;
517
518   for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
519     {
520       rtx set = XVECEXP (PATTERN (insn), 0, i);
521       gcc_assert (GET_CODE (set) == SET);
522       RTX_FRAME_RELATED_P (set) = 1;
523     }
524
525   frame_size -= link_size;
526
527   if (frame_size > 0)
528     {
529       /* Must use a call-clobbered PREG that isn't the static chain.  */
530       rtx tmpreg = gen_rtx_REG (Pmode, REG_P1);
531
532       frame_related_constant_load (tmpreg, -frame_size);
533       insn = emit_insn (gen_addsi3 (spreg, spreg, tmpreg));
534       RTX_FRAME_RELATED_P (insn) = 1;
535     }
536 }
537
538 /* Return the number of bytes we must reserve for outgoing arguments
539    in the current function's stack frame.  */
540
541 static HOST_WIDE_INT
542 arg_area_size (void)
543 {
544   if (current_function_outgoing_args_size)
545     {
546       if (current_function_outgoing_args_size >= FIXED_STACK_AREA)
547         return current_function_outgoing_args_size;
548       else
549         return FIXED_STACK_AREA;
550     }
551   return 0;
552 }
553
554 /* Save RETS and FP, and allocate a stack frame.  */
555
556 static void
557 do_link (rtx spreg, HOST_WIDE_INT frame_size)
558 {
559   frame_size += arg_area_size ();
560
561   if (stack_frame_needed_p ()
562       || (must_save_fp_p () && ! current_function_is_leaf))
563     emit_link_insn (spreg, frame_size);
564   else
565     {
566       if (! current_function_is_leaf)
567         {
568           rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
569                                             gen_rtx_PRE_DEC (Pmode, spreg)),
570                                bfin_rets_rtx);
571           rtx insn = emit_insn (pat);
572           RTX_FRAME_RELATED_P (insn) = 1;
573         }
574       if (must_save_fp_p ())
575         {
576           rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
577                                             gen_rtx_PRE_DEC (Pmode, spreg)),
578                                gen_rtx_REG (Pmode, REG_FP));
579           rtx insn = emit_insn (pat);
580           RTX_FRAME_RELATED_P (insn) = 1;
581         }
582       add_to_sp (spreg, -frame_size, 1);
583     }
584 }
585
586 /* Like do_link, but used for epilogues to deallocate the stack frame.  */
587
588 static void
589 do_unlink (rtx spreg, HOST_WIDE_INT frame_size)
590 {
591   frame_size += arg_area_size ();
592
593   if (stack_frame_needed_p ())
594     emit_insn (gen_unlink ());
595   else 
596     {
597       rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg));
598
599       add_to_sp (spreg, frame_size, 0);
600       if (must_save_fp_p ())
601         {
602           rtx fpreg = gen_rtx_REG (Pmode, REG_FP);
603           emit_move_insn (fpreg, postinc);
604           emit_insn (gen_rtx_USE (VOIDmode, fpreg));
605         }
606       if (! current_function_is_leaf)
607         {
608           emit_move_insn (bfin_rets_rtx, postinc);
609           emit_insn (gen_rtx_USE (VOIDmode, bfin_rets_rtx));
610         }
611     }
612 }
613
614 /* Generate a prologue suitable for a function of kind FKIND.  This is
615    called for interrupt and exception handler prologues.
616    SPREG contains (reg:SI REG_SP).  */
617
618 static void
619 expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind)
620 {
621   int i;
622   HOST_WIDE_INT frame_size = get_frame_size ();
623   rtx predec1 = gen_rtx_PRE_DEC (SImode, spreg);
624   rtx predec = gen_rtx_MEM (SImode, predec1);
625   rtx insn;
626   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
627   tree all = lookup_attribute ("saveall", attrs);
628   tree kspisusp = lookup_attribute ("kspisusp", attrs);
629
630   if (kspisusp)
631     {
632       insn = emit_move_insn (spreg, gen_rtx_REG (Pmode, REG_USP));
633       RTX_FRAME_RELATED_P (insn) = 1;
634     }
635
636   /* We need space on the stack in case we need to save the argument
637      registers.  */
638   if (fkind == EXCPT_HANDLER)
639     {
640       insn = emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (-12)));
641       RTX_FRAME_RELATED_P (insn) = 1;
642     }
643
644   insn = emit_move_insn (predec, gen_rtx_REG (SImode, REG_ASTAT));
645   RTX_FRAME_RELATED_P (insn) = 1;
646
647   expand_prologue_reg_save (spreg, all != NULL_TREE);
648
649   for (i = REG_P7 + 1; i < REG_CC; i++)
650     if (all 
651         || regs_ever_live[i]
652         || (!leaf_function_p () && call_used_regs[i]))
653       {
654         if (i == REG_A0 || i == REG_A1)
655           insn = emit_move_insn (gen_rtx_MEM (PDImode, predec1),
656                                  gen_rtx_REG (PDImode, i));
657         else
658           insn = emit_move_insn (predec, gen_rtx_REG (SImode, i));
659         RTX_FRAME_RELATED_P (insn) = 1;
660       }
661
662   if (lookup_attribute ("nesting", attrs))
663     {
664       rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX
665                                         : fkind == NMI_HANDLER ? REG_RETN
666                                         : REG_RETI));
667       insn = emit_move_insn (predec, srcreg);
668       RTX_FRAME_RELATED_P (insn) = 1;
669     }
670
671   do_link (spreg, frame_size);
672
673   if (fkind == EXCPT_HANDLER)
674     {
675       rtx r0reg = gen_rtx_REG (SImode, REG_R0);
676       rtx r1reg = gen_rtx_REG (SImode, REG_R1);
677       rtx r2reg = gen_rtx_REG (SImode, REG_R2);
678       rtx insn;
679
680       insn = emit_move_insn (r0reg, gen_rtx_REG (SImode, REG_SEQSTAT));
681       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
682                                             NULL_RTX);
683       insn = emit_insn (gen_ashrsi3 (r0reg, r0reg, GEN_INT (26)));
684       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
685                                             NULL_RTX);
686       insn = emit_insn (gen_ashlsi3 (r0reg, r0reg, GEN_INT (26)));
687       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
688                                             NULL_RTX);
689       insn = emit_move_insn (r1reg, spreg);
690       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
691                                             NULL_RTX);
692       insn = emit_move_insn (r2reg, gen_rtx_REG (Pmode, REG_FP));
693       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
694                                             NULL_RTX);
695       insn = emit_insn (gen_addsi3 (r2reg, r2reg, GEN_INT (8)));
696       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
697                                             NULL_RTX);
698     }
699 }
700
701 /* Generate an epilogue suitable for a function of kind FKIND.  This is
702    called for interrupt and exception handler epilogues.
703    SPREG contains (reg:SI REG_SP).  */
704
705 static void
706 expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind) 
707 {
708   int i;
709   rtx postinc1 = gen_rtx_POST_INC (SImode, spreg);
710   rtx postinc = gen_rtx_MEM (SImode, postinc1);
711   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
712   tree all = lookup_attribute ("saveall", attrs);
713
714   /* A slightly crude technique to stop flow from trying to delete "dead"
715      insns.  */
716   MEM_VOLATILE_P (postinc) = 1;
717
718   do_unlink (spreg, get_frame_size ());
719
720   if (lookup_attribute ("nesting", attrs))
721     {
722       rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX
723                                         : fkind == NMI_HANDLER ? REG_RETN
724                                         : REG_RETI));
725       emit_move_insn (srcreg, postinc);
726     }
727
728   for (i = REG_CC - 1; i > REG_P7; i--)
729     if (all
730         || regs_ever_live[i] 
731         || (!leaf_function_p () && call_used_regs[i]))
732       {
733         if (i == REG_A0 || i == REG_A1)
734           {
735             rtx mem = gen_rtx_MEM (PDImode, postinc1);
736             MEM_VOLATILE_P (mem) = 1;
737             emit_move_insn (gen_rtx_REG (PDImode, i), mem);
738           }
739         else
740           emit_move_insn (gen_rtx_REG (SImode, i), postinc);
741       }
742
743   expand_epilogue_reg_restore (spreg, all != NULL_TREE);
744
745   emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc);
746
747   /* Deallocate any space we left on the stack in case we needed to save the
748      argument registers.  */
749   if (fkind == EXCPT_HANDLER)
750     emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (12)));
751
752   emit_jump_insn (gen_return_internal (GEN_INT (fkind)));
753 }
754
755 /* Generate RTL for the prologue of the current function.  */
756
757 void
758 bfin_expand_prologue (void)
759 {
760   rtx insn;
761   HOST_WIDE_INT frame_size = get_frame_size ();
762   rtx spreg = gen_rtx_REG (Pmode, REG_SP);
763   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
764
765   if (fkind != SUBROUTINE)
766     {
767       expand_interrupt_handler_prologue (spreg, fkind);
768       return;
769     }
770
771   expand_prologue_reg_save (spreg, 0);
772
773   do_link (spreg, frame_size);
774
775   if (TARGET_ID_SHARED_LIBRARY
776       && (current_function_uses_pic_offset_table
777           || !current_function_is_leaf))
778     {
779       rtx addr;
780       
781       if (bfin_lib_id_given)
782         addr = plus_constant (pic_offset_table_rtx, -4 - bfin_library_id * 4);
783       else
784         addr = gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
785                              gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
786                                              UNSPEC_LIBRARY_OFFSET));
787       insn = emit_insn (gen_movsi (pic_offset_table_rtx,
788                                    gen_rtx_MEM (Pmode, addr)));
789       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL);
790     }
791 }
792
793 /* Generate RTL for the epilogue of the current function.  NEED_RETURN is zero
794    if this is for a sibcall.  EH_RETURN is nonzero if we're expanding an
795    eh_return pattern.  */
796
797 void
798 bfin_expand_epilogue (int need_return, int eh_return)
799 {
800   rtx spreg = gen_rtx_REG (Pmode, REG_SP);
801   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
802
803   if (fkind != SUBROUTINE)
804     {
805       expand_interrupt_handler_epilogue (spreg, fkind);
806       return;
807     }
808
809   do_unlink (spreg, get_frame_size ());
810
811   expand_epilogue_reg_restore (spreg, 0);
812
813   /* Omit the return insn if this is for a sibcall.  */
814   if (! need_return)
815     return;
816
817   if (eh_return)
818     emit_insn (gen_addsi3 (spreg, spreg, gen_rtx_REG (Pmode, REG_P2)));
819
820   emit_jump_insn (gen_return_internal (GEN_INT (SUBROUTINE)));
821 }
822 \f
823 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
824
825 int
826 bfin_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
827                            unsigned int new_reg)
828 {
829   /* Interrupt functions can only use registers that have already been
830      saved by the prologue, even if they would normally be
831      call-clobbered.  */
832
833   if (funkind (TREE_TYPE (current_function_decl)) != SUBROUTINE
834       && !regs_ever_live[new_reg])
835     return 0;
836
837   return 1;
838 }
839
840 /* Return the value of the return address for the frame COUNT steps up
841    from the current frame, after the prologue.
842    We punt for everything but the current frame by returning const0_rtx.  */
843
844 rtx
845 bfin_return_addr_rtx (int count)
846 {
847   if (count != 0)
848     return const0_rtx;
849
850   return get_hard_reg_initial_val (Pmode, REG_RETS);
851 }
852
853 /* Try machine-dependent ways of modifying an illegitimate address X
854    to be legitimate.  If we find one, return the new, valid address,
855    otherwise return NULL_RTX.
856
857    OLDX is the address as it was before break_out_memory_refs was called.
858    In some cases it is useful to look at this to decide what needs to be done.
859
860    MODE is the mode of the memory reference.  */
861
862 rtx
863 legitimize_address (rtx x ATTRIBUTE_UNUSED, rtx oldx ATTRIBUTE_UNUSED,
864                     enum machine_mode mode ATTRIBUTE_UNUSED)
865 {
866   return NULL_RTX;
867 }
868
869 /* This predicate is used to compute the length of a load/store insn.
870    OP is a MEM rtx, we return nonzero if its addressing mode requires a
871    32 bit instruction.  */
872
873 int
874 effective_address_32bit_p (rtx op, enum machine_mode mode) 
875 {
876   HOST_WIDE_INT offset;
877
878   mode = GET_MODE (op);
879   op = XEXP (op, 0);
880
881   if (GET_CODE (op) != PLUS)
882     {
883       gcc_assert (REG_P (op) || GET_CODE (op) == POST_INC
884                   || GET_CODE (op) == PRE_DEC || GET_CODE (op) == POST_DEC);
885       return 0;
886     }
887
888   offset = INTVAL (XEXP (op, 1));
889
890   /* All byte loads use a 16 bit offset.  */
891   if (GET_MODE_SIZE (mode) == 1)
892     return 1;
893
894   if (GET_MODE_SIZE (mode) == 4)
895     {
896       /* Frame pointer relative loads can use a negative offset, all others
897          are restricted to a small positive one.  */
898       if (XEXP (op, 0) == frame_pointer_rtx)
899         return offset < -128 || offset > 60;
900       return offset < 0 || offset > 60;
901     }
902
903   /* Must be HImode now.  */
904   return offset < 0 || offset > 30;
905 }
906
907 /* Return cost of the memory address ADDR.
908    All addressing modes are equally cheap on the Blackfin.  */
909
910 static int
911 bfin_address_cost (rtx addr ATTRIBUTE_UNUSED)
912 {
913   return 1;
914 }
915
916 /* Subroutine of print_operand; used to print a memory reference X to FILE.  */
917
918 void
919 print_address_operand (FILE *file, rtx x)
920 {
921   switch (GET_CODE (x))
922     {
923     case PLUS:
924       output_address (XEXP (x, 0));
925       fprintf (file, "+");
926       output_address (XEXP (x, 1));
927       break;
928
929     case PRE_DEC:
930       fprintf (file, "--");
931       output_address (XEXP (x, 0));    
932       break;
933     case POST_INC:
934       output_address (XEXP (x, 0));
935       fprintf (file, "++");
936       break;
937     case POST_DEC:
938       output_address (XEXP (x, 0));
939       fprintf (file, "--");
940       break;
941
942     default:
943       gcc_assert (GET_CODE (x) != MEM);
944       print_operand (file, x, 0);
945       break;
946     }
947 }
948
949 /* Adding intp DImode support by Tony
950  * -- Q: (low  word)
951  * -- R: (high word)
952  */
953
954 void
955 print_operand (FILE *file, rtx x, char code)
956 {
957   enum machine_mode mode = GET_MODE (x);
958
959   switch (code)
960     {
961     case 'j':
962       switch (GET_CODE (x))
963         {
964         case EQ:
965           fprintf (file, "e");
966           break;
967         case NE:
968           fprintf (file, "ne");
969           break;
970         case GT:
971           fprintf (file, "g");
972           break;
973         case LT:
974           fprintf (file, "l");
975           break;
976         case GE:
977           fprintf (file, "ge");
978           break;
979         case LE:
980           fprintf (file, "le");
981           break;
982         case GTU:
983           fprintf (file, "g");
984           break;
985         case LTU:
986           fprintf (file, "l");
987           break;
988         case GEU:
989           fprintf (file, "ge");
990           break;
991         case LEU:
992           fprintf (file, "le");
993           break;
994         default:
995           output_operand_lossage ("invalid %%j value");
996         }
997       break;
998     
999     case 'J':                                    /* reverse logic */
1000       switch (GET_CODE(x))
1001         {
1002         case EQ:
1003           fprintf (file, "ne");
1004           break;
1005         case NE:
1006           fprintf (file, "e");
1007           break;
1008         case GT:
1009           fprintf (file, "le");
1010           break;
1011         case LT:
1012           fprintf (file, "ge");
1013           break;
1014         case GE:
1015           fprintf (file, "l");
1016           break;
1017         case LE:
1018           fprintf (file, "g");
1019           break;
1020         case GTU:
1021           fprintf (file, "le");
1022           break;
1023         case LTU:
1024           fprintf (file, "ge");
1025           break;
1026         case GEU:
1027           fprintf (file, "l");
1028           break;
1029         case LEU:
1030           fprintf (file, "g");
1031           break;
1032         default:
1033           output_operand_lossage ("invalid %%J value");
1034         }
1035       break;
1036
1037     default:
1038       switch (GET_CODE (x))
1039         {
1040         case REG:
1041           if (code == 'h')
1042             {
1043               gcc_assert (REGNO (x) < 32);
1044               fprintf (file, "%s", short_reg_names[REGNO (x)]);
1045               /*fprintf (file, "\n%d\n ", REGNO (x));*/
1046               break;
1047             }
1048           else if (code == 'd')
1049             {
1050               gcc_assert (REGNO (x) < 32);
1051               fprintf (file, "%s", high_reg_names[REGNO (x)]);
1052               break;
1053             }
1054           else if (code == 'w')
1055             {
1056               gcc_assert (REGNO (x) == REG_A0 || REGNO (x) == REG_A1);
1057               fprintf (file, "%s.w", reg_names[REGNO (x)]);
1058             }
1059           else if (code == 'x')
1060             {
1061               gcc_assert (REGNO (x) == REG_A0 || REGNO (x) == REG_A1);
1062               fprintf (file, "%s.x", reg_names[REGNO (x)]);
1063             }
1064           else if (code == 'D')
1065             {
1066               fprintf (file, "%s", dregs_pair_names[REGNO (x)]);
1067             }
1068           else if (code == 'H')
1069             {
1070               gcc_assert (mode == DImode || mode == DFmode);
1071               gcc_assert (REG_P (x));
1072               fprintf (file, "%s", reg_names[REGNO (x) + 1]);
1073             }
1074           else if (code == 'T')
1075             {
1076               gcc_assert (D_REGNO_P (REGNO (x)));
1077               fprintf (file, "%s", byte_reg_names[REGNO (x)]);
1078             }
1079           else 
1080             fprintf (file, "%s", reg_names[REGNO (x)]);
1081           break;
1082
1083         case MEM:
1084           fputc ('[', file);
1085           x = XEXP (x,0);
1086           print_address_operand (file, x);
1087           fputc (']', file);
1088           break;
1089
1090         case CONST_INT:
1091           /* Moves to half registers with d or h modifiers always use unsigned
1092              constants.  */
1093           if (code == 'd')
1094             x = GEN_INT ((INTVAL (x) >> 16) & 0xffff);
1095           else if (code == 'h')
1096             x = GEN_INT (INTVAL (x) & 0xffff);
1097           else if (code == 'X')
1098             x = GEN_INT (exact_log2 (0xffffffff & INTVAL (x)));
1099           else if (code == 'Y')
1100             x = GEN_INT (exact_log2 (0xffffffff & ~INTVAL (x)));
1101           else if (code == 'Z')
1102             /* Used for LINK insns.  */
1103             x = GEN_INT (-8 - INTVAL (x));
1104
1105           /* fall through */
1106
1107         case SYMBOL_REF:
1108           output_addr_const (file, x);
1109           if (code == 'G' && flag_pic)
1110             fprintf (file, "@GOT");
1111           break;
1112
1113         case CONST_DOUBLE:
1114           output_operand_lossage ("invalid const_double operand");
1115           break;
1116
1117         case UNSPEC:
1118           switch (XINT (x, 1))
1119             {
1120             case UNSPEC_MOVE_PIC:
1121               output_addr_const (file, XVECEXP (x, 0, 0));
1122               fprintf (file, "@GOT");
1123               break;
1124
1125             case UNSPEC_LIBRARY_OFFSET:
1126               fprintf (file, "_current_shared_library_p5_offset_");
1127               break;
1128
1129             default:
1130               gcc_unreachable ();
1131             }
1132           break;
1133
1134         default:
1135           output_addr_const (file, x);
1136         }
1137     }
1138 }
1139 \f
1140 /* Argument support functions.  */
1141
1142 /* Initialize a variable CUM of type CUMULATIVE_ARGS
1143    for a call to a function whose data type is FNTYPE.
1144    For a library call, FNTYPE is 0.  
1145    VDSP C Compiler manual, our ABI says that
1146    first 3 words of arguments will use R0, R1 and R2.
1147 */
1148
1149 void
1150 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype ATTRIBUTE_UNUSED,
1151                       rtx libname ATTRIBUTE_UNUSED)
1152 {
1153   static CUMULATIVE_ARGS zero_cum;
1154
1155   *cum = zero_cum;
1156
1157   /* Set up the number of registers to use for passing arguments.  */
1158
1159   cum->nregs = max_arg_registers;
1160   cum->arg_regs = arg_regs;
1161
1162   return;
1163 }
1164
1165 /* Update the data in CUM to advance over an argument
1166    of mode MODE and data type TYPE.
1167    (TYPE is null for libcalls where that information may not be available.)  */
1168
1169 void
1170 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1171                       int named ATTRIBUTE_UNUSED)
1172 {
1173   int count, bytes, words;
1174
1175   bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1176   words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1177
1178   cum->words += words;
1179   cum->nregs -= words;
1180
1181   if (cum->nregs <= 0)
1182     {
1183       cum->nregs = 0;
1184       cum->arg_regs = NULL;
1185     }
1186   else
1187     {
1188       for (count = 1; count <= words; count++)
1189         cum->arg_regs++;
1190     }
1191
1192   return;
1193 }
1194
1195 /* Define where to put the arguments to a function.
1196    Value is zero to push the argument on the stack,
1197    or a hard register in which to store the argument.
1198
1199    MODE is the argument's machine mode.
1200    TYPE is the data type of the argument (as a tree).
1201     This is null for libcalls where that information may
1202     not be available.
1203    CUM is a variable of type CUMULATIVE_ARGS which gives info about
1204     the preceding args and about the function being called.
1205    NAMED is nonzero if this argument is a named parameter
1206     (otherwise it is an extra parameter matching an ellipsis).  */
1207
1208 struct rtx_def *
1209 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1210               int named ATTRIBUTE_UNUSED)
1211 {
1212   int bytes
1213     = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1214
1215   if (bytes == -1)
1216     return NULL_RTX;
1217
1218   if (cum->nregs)
1219     return gen_rtx_REG (mode, *(cum->arg_regs));
1220
1221   return NULL_RTX;
1222 }
1223
1224 /* For an arg passed partly in registers and partly in memory,
1225    this is the number of bytes passed in registers.
1226    For args passed entirely in registers or entirely in memory, zero.
1227
1228    Refer VDSP C Compiler manual, our ABI.
1229    First 3 words are in registers. So, if a an argument is larger
1230    than the registers available, it will span the register and
1231    stack.   */
1232
1233 static int
1234 bfin_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1235                         tree type ATTRIBUTE_UNUSED,
1236                         bool named ATTRIBUTE_UNUSED)
1237 {
1238   int bytes
1239     = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1240   int bytes_left = cum->nregs * UNITS_PER_WORD;
1241   
1242   if (bytes == -1)
1243     return 0;
1244
1245   if (bytes_left == 0)
1246     return 0;
1247   if (bytes > bytes_left)
1248     return bytes_left;
1249   return 0;
1250 }
1251
1252 /* Variable sized types are passed by reference.  */
1253
1254 static bool
1255 bfin_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
1256                         enum machine_mode mode ATTRIBUTE_UNUSED,
1257                         tree type, bool named ATTRIBUTE_UNUSED)
1258 {
1259   return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
1260 }
1261
1262 /* Decide whether a type should be returned in memory (true)
1263    or in a register (false).  This is called by the macro
1264    RETURN_IN_MEMORY.  */
1265
1266 int
1267 bfin_return_in_memory (tree type)
1268 {
1269   int size;
1270   enum machine_mode mode = TYPE_MODE (type);
1271
1272   if (mode == BLKmode)
1273     return 1;
1274   size = int_size_in_bytes (type);      
1275   if (VECTOR_MODE_P (mode) || mode == TImode)
1276     {
1277       /* User-created vectors small enough to fit in REG.  */
1278       if (size < 8)
1279         return 0;
1280       if (size == 8 || size == 16)
1281         return 1;
1282     }
1283
1284   if (size > 12)
1285     return 1;
1286   return 0;
1287 }
1288
1289 /* Register in which address to store a structure value
1290    is passed to a function.  */
1291 static rtx
1292 bfin_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
1293                       int incoming ATTRIBUTE_UNUSED)
1294 {
1295   return gen_rtx_REG (Pmode, REG_P0);
1296 }
1297
1298 /* Return true when register may be used to pass function parameters.  */
1299
1300 bool 
1301 function_arg_regno_p (int n)
1302 {
1303   int i;
1304   for (i = 0; arg_regs[i] != -1; i++)
1305     if (n == arg_regs[i])
1306       return true;
1307   return false;
1308 }
1309
1310 /* Returns 1 if OP contains a symbol reference */
1311
1312 int
1313 symbolic_reference_mentioned_p (rtx op)
1314 {
1315   register const char *fmt;
1316   register int i;
1317
1318   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1319     return 1;
1320
1321   fmt = GET_RTX_FORMAT (GET_CODE (op));
1322   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1323     {
1324       if (fmt[i] == 'E')
1325         {
1326           register int j;
1327
1328           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1329             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1330               return 1;
1331         }
1332
1333       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1334         return 1;
1335     }
1336
1337   return 0;
1338 }
1339
1340 /* Decide whether we can make a sibling call to a function.  DECL is the
1341    declaration of the function being targeted by the call and EXP is the
1342    CALL_EXPR representing the call.  */
1343
1344 static bool
1345 bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
1346                               tree exp ATTRIBUTE_UNUSED)
1347 {
1348   return true;
1349 }
1350 \f
1351 /* Emit RTL insns to initialize the variable parts of a trampoline at
1352    TRAMP. FNADDR is an RTX for the address of the function's pure
1353    code.  CXT is an RTX for the static chain value for the function.  */
1354
1355 void
1356 initialize_trampoline (tramp, fnaddr, cxt)
1357      rtx tramp, fnaddr, cxt;
1358 {
1359   rtx t1 = copy_to_reg (fnaddr);
1360   rtx t2 = copy_to_reg (cxt);
1361   rtx addr;
1362
1363   addr = memory_address (Pmode, plus_constant (tramp, 2));
1364   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t1));
1365   emit_insn (gen_ashrsi3 (t1, t1, GEN_INT (16)));
1366   addr = memory_address (Pmode, plus_constant (tramp, 6));
1367   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t1));
1368
1369   addr = memory_address (Pmode, plus_constant (tramp, 10));
1370   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t2));
1371   emit_insn (gen_ashrsi3 (t2, t2, GEN_INT (16)));
1372   addr = memory_address (Pmode, plus_constant (tramp, 14));
1373   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t2));
1374 }
1375
1376 /* Legitimize PIC addresses.  If the address is already position-independent,
1377    we return ORIG.  Newly generated position-independent addresses go into a
1378    reg.  This is REG if nonzero, otherwise we allocate register(s) as
1379    necessary.  */
1380
1381 rtx
1382 legitimize_pic_address (rtx orig, rtx reg)
1383 {
1384   rtx addr = orig;
1385   rtx new = orig;
1386
1387   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
1388     {
1389       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
1390         reg = new = orig;
1391       else
1392         {
1393           if (reg == 0)
1394             {
1395               gcc_assert (!no_new_pseudos);
1396               reg = gen_reg_rtx (Pmode);
1397             }
1398
1399           if (flag_pic == 2)
1400             {
1401               emit_insn (gen_movsi_high_pic (reg, addr));
1402               emit_insn (gen_movsi_low_pic (reg, reg, addr));
1403               emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
1404               new = gen_rtx_MEM (Pmode, reg);
1405             }
1406           else
1407             {
1408               rtx tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
1409                                         UNSPEC_MOVE_PIC);
1410               new = gen_rtx_MEM (Pmode,
1411                                  gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
1412                                                tmp));
1413             }
1414           emit_move_insn (reg, new);
1415         }
1416       current_function_uses_pic_offset_table = 1;
1417       return reg;
1418     }
1419
1420   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1421     {
1422       rtx base;
1423
1424       if (GET_CODE (addr) == CONST)
1425         {
1426           addr = XEXP (addr, 0);
1427           gcc_assert (GET_CODE (addr) == PLUS);
1428         }
1429
1430       if (XEXP (addr, 0) == pic_offset_table_rtx)
1431         return orig;
1432
1433       if (reg == 0)
1434         {
1435           gcc_assert (!no_new_pseudos);
1436           reg = gen_reg_rtx (Pmode);
1437         }
1438
1439       base = legitimize_pic_address (XEXP (addr, 0), reg);
1440       addr = legitimize_pic_address (XEXP (addr, 1),
1441                                      base == reg ? NULL_RTX : reg);
1442
1443       if (GET_CODE (addr) == CONST_INT)
1444         {
1445           gcc_assert (! reload_in_progress && ! reload_completed);
1446           addr = force_reg (Pmode, addr);
1447         }
1448
1449       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
1450         {
1451           base = gen_rtx_PLUS (Pmode, base, XEXP (addr, 0));
1452           addr = XEXP (addr, 1);
1453         }
1454
1455       return gen_rtx_PLUS (Pmode, base, addr);
1456     }
1457
1458   return new;
1459 }
1460
1461 /* Emit insns to move operands[1] into operands[0].  */
1462
1463 void
1464 emit_pic_move (rtx *operands, enum machine_mode mode ATTRIBUTE_UNUSED)
1465 {
1466   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
1467
1468   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
1469     operands[1] = force_reg (SImode, operands[1]);
1470   else
1471     operands[1] = legitimize_pic_address (operands[1], temp);
1472 }
1473
1474 /* Expand a move operation in mode MODE.  The operands are in OPERANDS.  */
1475
1476 void
1477 expand_move (rtx *operands, enum machine_mode mode)
1478 {
1479   if (flag_pic && SYMBOLIC_CONST (operands[1]))
1480     emit_pic_move (operands, mode);
1481
1482   /* Don't generate memory->memory or constant->memory moves, go through a
1483      register */
1484   else if ((reload_in_progress | reload_completed) == 0
1485            && GET_CODE (operands[0]) == MEM
1486            && GET_CODE (operands[1]) != REG)
1487     operands[1] = force_reg (mode, operands[1]);
1488 }
1489 \f
1490 /* Split one or more DImode RTL references into pairs of SImode
1491    references.  The RTL can be REG, offsettable MEM, integer constant, or
1492    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
1493    split and "num" is its length.  lo_half and hi_half are output arrays
1494    that parallel "operands".  */
1495
1496 void
1497 split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
1498 {
1499   while (num--)
1500     {
1501       rtx op = operands[num];
1502
1503       /* simplify_subreg refuse to split volatile memory addresses,
1504          but we still have to handle it.  */
1505       if (GET_CODE (op) == MEM)
1506         {
1507           lo_half[num] = adjust_address (op, SImode, 0);
1508           hi_half[num] = adjust_address (op, SImode, 4);
1509         }
1510       else
1511         {
1512           lo_half[num] = simplify_gen_subreg (SImode, op,
1513                                               GET_MODE (op) == VOIDmode
1514                                               ? DImode : GET_MODE (op), 0);
1515           hi_half[num] = simplify_gen_subreg (SImode, op,
1516                                               GET_MODE (op) == VOIDmode
1517                                               ? DImode : GET_MODE (op), 4);
1518         }
1519     }
1520 }
1521 \f
1522 /* Expand a call instruction.  FNADDR is the call target, RETVAL the return value.
1523    SIBCALL is nonzero if this is a sibling call.  */
1524
1525 void
1526 bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, int sibcall)
1527 {
1528   rtx use = NULL, call;
1529
1530   /* Static functions and indirect calls don't need the pic register.  */
1531   if (flag_pic
1532       && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
1533       && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
1534     use_reg (&use, pic_offset_table_rtx);
1535
1536   if (! call_insn_operand (XEXP (fnaddr, 0), Pmode))
1537     {
1538       fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
1539       fnaddr = gen_rtx_MEM (Pmode, fnaddr);
1540     }
1541   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
1542
1543   if (retval)
1544     call = gen_rtx_SET (VOIDmode, retval, call);
1545   if (sibcall)
1546     {
1547       rtx pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
1548       XVECEXP (pat, 0, 0) = call;
1549       XVECEXP (pat, 0, 1) = gen_rtx_RETURN (VOIDmode);
1550       call = pat;
1551     }
1552   call = emit_call_insn (call);
1553   if (use)
1554     CALL_INSN_FUNCTION_USAGE (call) = use;
1555 }
1556 \f
1557 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE.  */
1558
1559 int
1560 hard_regno_mode_ok (int regno, enum machine_mode mode)
1561 {
1562   /* Allow only dregs to store value of mode HI or QI */
1563   enum reg_class class = REGNO_REG_CLASS (regno);
1564
1565   if (mode == CCmode)
1566     return 0;
1567
1568   if (mode == V2HImode)
1569     return D_REGNO_P (regno);
1570   if (class == CCREGS)
1571     return mode == BImode;
1572   if (mode == PDImode)
1573     return regno == REG_A0 || regno == REG_A1;
1574   if (mode == SImode
1575       && TEST_HARD_REG_BIT (reg_class_contents[PROLOGUE_REGS], regno))
1576     return 1;
1577       
1578   return TEST_HARD_REG_BIT (reg_class_contents[MOST_REGS], regno);
1579 }
1580
1581 /* Implements target hook vector_mode_supported_p.  */
1582
1583 static bool
1584 bfin_vector_mode_supported_p (enum machine_mode mode)
1585 {
1586   return mode == V2HImode;
1587 }
1588
1589 /* Return the cost of moving data from a register in class CLASS1 to
1590    one in class CLASS2.  A cost of 2 is the default.  */
1591
1592 int
1593 bfin_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1594                          enum reg_class class1, enum reg_class class2)
1595 {
1596   /* If optimizing for size, always prefer reg-reg over reg-memory moves.  */
1597   if (optimize_size)
1598     return 2;
1599
1600   /* There are some stalls involved when moving from a DREG to a different
1601      class reg, and using the value in one of the following instructions.
1602      Attempt to model this by slightly discouraging such moves.  */
1603   if (class1 == DREGS && class2 != DREGS)
1604     return 2 * 2;
1605
1606   return 2;
1607 }
1608
1609 /* Return the cost of moving data of mode M between a
1610    register and memory.  A value of 2 is the default; this cost is
1611    relative to those in `REGISTER_MOVE_COST'.
1612
1613    ??? In theory L1 memory has single-cycle latency.  We should add a switch
1614    that tells the compiler whether we expect to use only L1 memory for the
1615    program; it'll make the costs more accurate.  */
1616
1617 int
1618 bfin_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1619                        enum reg_class class,
1620                        int in ATTRIBUTE_UNUSED)
1621 {
1622   /* Make memory accesses slightly more expensive than any register-register
1623      move.  Also, penalize non-DP registers, since they need secondary
1624      reloads to load and store.  */
1625   if (! reg_class_subset_p (class, DPREGS))
1626     return 10;
1627
1628   return 8;
1629 }
1630
1631 /* Inform reload about cases where moving X with a mode MODE to a register in
1632    CLASS requires an extra scratch register.  Return the class needed for the
1633    scratch register.  */
1634
1635 enum reg_class
1636 secondary_input_reload_class (enum reg_class class, enum machine_mode mode,
1637                               rtx x)
1638 {
1639   /* If we have HImode or QImode, we can only use DREGS as secondary registers;
1640      in most other cases we can also use PREGS.  */
1641   enum reg_class default_class = GET_MODE_SIZE (mode) >= 4 ? DPREGS : DREGS;
1642   enum reg_class x_class = NO_REGS;
1643   enum rtx_code code = GET_CODE (x);
1644
1645   if (code == SUBREG)
1646     x = SUBREG_REG (x), code = GET_CODE (x);
1647   if (REG_P (x))
1648     {
1649       int regno = REGNO (x);
1650       if (regno >= FIRST_PSEUDO_REGISTER)
1651         regno = reg_renumber[regno];
1652
1653       if (regno == -1)
1654         code = MEM;
1655       else
1656         x_class = REGNO_REG_CLASS (regno);
1657     }
1658
1659   /* We can be asked to reload (plus (FP) (large_constant)) into a DREG.
1660      This happens as a side effect of register elimination, and we need
1661      a scratch register to do it.  */
1662   if (fp_plus_const_operand (x, mode))
1663     {
1664       rtx op2 = XEXP (x, 1);
1665       int large_constant_p = ! CONST_7BIT_IMM_P (INTVAL (op2));
1666
1667       if (class == PREGS || class == PREGS_CLOBBERED)
1668         return NO_REGS;
1669       /* If destination is a DREG, we can do this without a scratch register
1670          if the constant is valid for an add instruction.  */
1671       if (class == DREGS || class == DPREGS)
1672         return large_constant_p ? PREGS : NO_REGS;
1673       /* Reloading to anything other than a DREG?  Use a PREG scratch
1674          register.  */
1675       return PREGS;
1676     }
1677
1678   /* Data can usually be moved freely between registers of most classes.
1679      AREGS are an exception; they can only move to or from another register
1680      in AREGS or one in DREGS.  They can also be assigned the constant 0.  */
1681   if (x_class == AREGS)
1682     return class == DREGS || class == AREGS ? NO_REGS : DREGS;
1683
1684   if (class == AREGS)
1685     {
1686       if (x != const0_rtx && x_class != DREGS)
1687         return DREGS;
1688       else
1689         return NO_REGS;
1690     }
1691
1692   /* CCREGS can only be moved from/to DREGS.  */
1693   if (class == CCREGS && x_class != DREGS)
1694     return DREGS;
1695   if (x_class == CCREGS && class != DREGS)
1696     return DREGS;
1697   /* All registers other than AREGS can load arbitrary constants.  The only
1698      case that remains is MEM.  */
1699   if (code == MEM)
1700     if (! reg_class_subset_p (class, default_class))
1701       return default_class;
1702   return NO_REGS;
1703 }
1704
1705 /* Like secondary_input_reload_class; and all we do is call that function.  */
1706
1707 enum reg_class
1708 secondary_output_reload_class (enum reg_class class, enum machine_mode mode,
1709                                rtx x)
1710 {
1711   return secondary_input_reload_class (class, mode, x);
1712 }
1713 \f
1714 /* Implement TARGET_HANDLE_OPTION.  */
1715
1716 static bool
1717 bfin_handle_option (size_t code, const char *arg, int value)
1718 {
1719   switch (code)
1720     {
1721     case OPT_mshared_library_id_:
1722       if (value > MAX_LIBRARY_ID)
1723         error ("-mshared-library-id=%s is not between 0 and %d",
1724                arg, MAX_LIBRARY_ID);
1725       else
1726         bfin_library_id = value;
1727       bfin_lib_id_given = 1;
1728       return true;
1729
1730     default:
1731       return true;
1732     }
1733 }
1734
1735 /* Implement the macro OVERRIDE_OPTIONS.  */
1736
1737 void
1738 override_options (void)
1739 {
1740   if (TARGET_OMIT_LEAF_FRAME_POINTER)
1741     flag_omit_frame_pointer = 1;
1742
1743   /* Library identification */
1744   if (bfin_lib_id_given && ! TARGET_ID_SHARED_LIBRARY)
1745     error ("-mshared-library-id= specified without -mid-shared-library");
1746
1747   if (TARGET_ID_SHARED_LIBRARY)
1748     /* ??? Provide a way to use a bigger GOT.  */
1749     flag_pic = 1;
1750
1751   flag_schedule_insns = 0;
1752 }
1753
1754 /* Return the destination address of BRANCH.
1755    We need to use this instead of get_attr_length, because the
1756    cbranch_with_nops pattern conservatively sets its length to 6, and
1757    we still prefer to use shorter sequences.  */
1758
1759 static int
1760 branch_dest (rtx branch)
1761 {
1762   rtx dest;
1763   int dest_uid;
1764   rtx pat = PATTERN (branch);
1765   if (GET_CODE (pat) == PARALLEL)
1766     pat = XVECEXP (pat, 0, 0);
1767   dest = SET_SRC (pat);
1768   if (GET_CODE (dest) == IF_THEN_ELSE)
1769     dest = XEXP (dest, 1);
1770   dest = XEXP (dest, 0);
1771   dest_uid = INSN_UID (dest);
1772   return INSN_ADDRESSES (dest_uid);
1773 }
1774
1775 /* Return nonzero if INSN is annotated with a REG_BR_PROB note that indicates
1776    it's a branch that's predicted taken.  */
1777
1778 static int
1779 cbranch_predicted_taken_p (rtx insn)
1780 {
1781   rtx x = find_reg_note (insn, REG_BR_PROB, 0);
1782
1783   if (x)
1784     {
1785       int pred_val = INTVAL (XEXP (x, 0));
1786
1787       return pred_val >= REG_BR_PROB_BASE / 2;
1788     }
1789
1790   return 0;
1791 }
1792
1793 /* Templates for use by asm_conditional_branch.  */
1794
1795 static const char *ccbranch_templates[][3] = {
1796   { "if !cc jump %3;",  "if cc jump 4 (bp); jump.s %3;",  "if cc jump 6 (bp); jump.l %3;" },
1797   { "if cc jump %3;",   "if !cc jump 4 (bp); jump.s %3;", "if !cc jump 6 (bp); jump.l %3;" },
1798   { "if !cc jump %3 (bp);",  "if cc jump 4; jump.s %3;",  "if cc jump 6; jump.l %3;" },
1799   { "if cc jump %3 (bp);",  "if !cc jump 4; jump.s %3;",  "if !cc jump 6; jump.l %3;" },
1800 };
1801
1802 /* Output INSN, which is a conditional branch instruction with operands
1803    OPERANDS.
1804
1805    We deal with the various forms of conditional branches that can be generated
1806    by bfin_reorg to prevent the hardware from doing speculative loads, by
1807    - emitting a sufficient number of nops, if N_NOPS is nonzero, or
1808    - always emitting the branch as predicted taken, if PREDICT_TAKEN is true.
1809    Either of these is only necessary if the branch is short, otherwise the
1810    template we use ends in an unconditional jump which flushes the pipeline
1811    anyway.  */
1812
1813 void
1814 asm_conditional_branch (rtx insn, rtx *operands, int n_nops, int predict_taken)
1815 {
1816   int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
1817   /* Note : offset for instructions like if cc jmp; jump.[sl] offset
1818             is to be taken from start of if cc rather than jump.
1819             Range for jump.s is (-4094, 4096) instead of (-4096, 4094)
1820   */
1821   int len = (offset >= -1024 && offset <= 1022 ? 0
1822              : offset >= -4094 && offset <= 4096 ? 1
1823              : 2);
1824   int bp = predict_taken && len == 0 ? 1 : cbranch_predicted_taken_p (insn);
1825   int idx = (bp << 1) | (GET_CODE (operands[0]) == EQ ? BRF : BRT);
1826   output_asm_insn (ccbranch_templates[idx][len], operands);
1827   gcc_assert (n_nops == 0 || !bp);
1828   if (len == 0)
1829     while (n_nops-- > 0)
1830       output_asm_insn ("nop;", NULL);
1831 }
1832
1833 /* Emit rtl for a comparison operation CMP in mode MODE.  Operands have been
1834    stored in bfin_compare_op0 and bfin_compare_op1 already.  */
1835
1836 rtx
1837 bfin_gen_compare (rtx cmp, enum machine_mode mode ATTRIBUTE_UNUSED)
1838 {
1839   enum rtx_code code1, code2;
1840   rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1841   rtx tem = bfin_cc_rtx;
1842   enum rtx_code code = GET_CODE (cmp);
1843
1844   /* If we have a BImode input, then we already have a compare result, and
1845      do not need to emit another comparison.  */
1846   if (GET_MODE (op0) == BImode)
1847     {
1848       gcc_assert ((code == NE || code == EQ) && op1 == const0_rtx);
1849       tem = op0, code2 = code;
1850     }
1851   else
1852     {
1853       switch (code) {
1854         /* bfin has these conditions */
1855       case EQ:
1856       case LT:
1857       case LE:
1858       case LEU:
1859       case LTU:
1860         code1 = code;
1861         code2 = NE;
1862         break;
1863       default:
1864         code1 = reverse_condition (code);
1865         code2 = EQ;
1866         break;
1867       }
1868       emit_insn (gen_rtx_SET (BImode, tem,
1869                               gen_rtx_fmt_ee (code1, BImode, op0, op1)));
1870     }
1871
1872   return gen_rtx_fmt_ee (code2, BImode, tem, CONST0_RTX (BImode));
1873 }
1874 \f
1875 /* Return nonzero iff C has exactly one bit set if it is interpreted
1876    as a 32 bit constant.  */
1877
1878 int
1879 log2constp (unsigned HOST_WIDE_INT c)
1880 {
1881   c &= 0xFFFFFFFF;
1882   return c != 0 && (c & (c-1)) == 0;
1883 }
1884
1885 /* Returns the number of consecutive least significant zeros in the binary
1886    representation of *V.
1887    We modify *V to contain the original value arithmetically shifted right by
1888    the number of zeroes.  */
1889
1890 static int
1891 shiftr_zero (HOST_WIDE_INT *v)
1892 {
1893   unsigned HOST_WIDE_INT tmp = *v;
1894   unsigned HOST_WIDE_INT sgn;
1895   int n = 0;
1896
1897   if (tmp == 0)
1898     return 0;
1899
1900   sgn = tmp & ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1));
1901   while ((tmp & 0x1) == 0 && n <= 32)
1902     {
1903       tmp = (tmp >> 1) | sgn;
1904       n++;
1905     }
1906   *v = tmp;
1907   return n;
1908 }
1909
1910 /* After reload, split the load of an immediate constant.  OPERANDS are the
1911    operands of the movsi_insn pattern which we are splitting.  We return
1912    nonzero if we emitted a sequence to load the constant, zero if we emitted
1913    nothing because we want to use the splitter's default sequence.  */
1914
1915 int
1916 split_load_immediate (rtx operands[])
1917 {
1918   HOST_WIDE_INT val = INTVAL (operands[1]);
1919   HOST_WIDE_INT tmp;
1920   HOST_WIDE_INT shifted = val;
1921   HOST_WIDE_INT shifted_compl = ~val;
1922   int num_zero = shiftr_zero (&shifted);
1923   int num_compl_zero = shiftr_zero (&shifted_compl);
1924   unsigned int regno = REGNO (operands[0]);
1925   enum reg_class class1 = REGNO_REG_CLASS (regno);
1926
1927   /* This case takes care of single-bit set/clear constants, which we could
1928      also implement with BITSET/BITCLR.  */
1929   if (num_zero
1930       && shifted >= -32768 && shifted < 65536
1931       && (D_REGNO_P (regno)
1932           || (regno >= REG_P0 && regno <= REG_P7 && num_zero <= 2)))
1933     {
1934       emit_insn (gen_movsi (operands[0], GEN_INT (shifted)));
1935       emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (num_zero)));
1936       return 1;
1937     }
1938
1939   tmp = val & 0xFFFF;
1940   tmp |= -(tmp & 0x8000);
1941
1942   /* If high word has one bit set or clear, try to use a bit operation.  */
1943   if (D_REGNO_P (regno))
1944     {
1945       if (log2constp (val & 0xFFFF0000))
1946         {
1947           emit_insn (gen_movsi (operands[0], GEN_INT (val & 0xFFFF)));
1948           emit_insn (gen_iorsi3 (operands[0], operands[0], GEN_INT (val & 0xFFFF0000)));
1949           return 1;
1950         }
1951       else if (log2constp (val | 0xFFFF) && (val & 0x8000) != 0)
1952         {
1953           emit_insn (gen_movsi (operands[0], GEN_INT (tmp)));
1954           emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (val | 0xFFFF)));
1955         }
1956     }
1957
1958   if (D_REGNO_P (regno))
1959     {
1960       if (CONST_7BIT_IMM_P (tmp))
1961         {
1962           emit_insn (gen_movsi (operands[0], GEN_INT (tmp)));
1963           emit_insn (gen_movstricthi_high (operands[0], GEN_INT (val & -65536)));
1964           return 1;
1965         }
1966
1967       if ((val & 0xFFFF0000) == 0)
1968         {
1969           emit_insn (gen_movsi (operands[0], const0_rtx));
1970           emit_insn (gen_movsi_low (operands[0], operands[0], operands[1]));
1971           return 1;
1972         }
1973
1974       if ((val & 0xFFFF0000) == 0xFFFF0000)
1975         {
1976           emit_insn (gen_movsi (operands[0], constm1_rtx));
1977           emit_insn (gen_movsi_low (operands[0], operands[0], operands[1]));
1978           return 1;
1979         }
1980     }
1981
1982   /* Need DREGs for the remaining case.  */
1983   if (regno > REG_R7)
1984     return 0;
1985
1986   if (optimize_size
1987       && num_compl_zero && CONST_7BIT_IMM_P (shifted_compl))
1988     {
1989       /* If optimizing for size, generate a sequence that has more instructions
1990          but is shorter.  */
1991       emit_insn (gen_movsi (operands[0], GEN_INT (shifted_compl)));
1992       emit_insn (gen_ashlsi3 (operands[0], operands[0],
1993                               GEN_INT (num_compl_zero)));
1994       emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
1995       return 1;
1996     }
1997   return 0;
1998 }
1999 \f
2000 /* Return true if the legitimate memory address for a memory operand of mode
2001    MODE.  Return false if not.  */
2002
2003 static bool
2004 bfin_valid_add (enum machine_mode mode, HOST_WIDE_INT value)
2005 {
2006   unsigned HOST_WIDE_INT v = value > 0 ? value : -value;
2007   int sz = GET_MODE_SIZE (mode);
2008   int shift = sz == 1 ? 0 : sz == 2 ? 1 : 2;
2009   /* The usual offsettable_memref machinery doesn't work so well for this
2010      port, so we deal with the problem here.  */
2011   unsigned HOST_WIDE_INT mask = sz == 8 ? 0x7ffe : 0x7fff;
2012   return (v & ~(mask << shift)) == 0;
2013 }
2014
2015 static bool
2016 bfin_valid_reg_p (unsigned int regno, int strict)
2017 {
2018   return ((strict && REGNO_OK_FOR_BASE_STRICT_P (regno))
2019           || (!strict && REGNO_OK_FOR_BASE_NONSTRICT_P (regno)));
2020 }
2021
2022 bool
2023 bfin_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
2024 {
2025   switch (GET_CODE (x)) {
2026   case REG:
2027     if (bfin_valid_reg_p (REGNO (x), strict))
2028       return true;
2029     break;
2030   case PLUS:
2031     if (REG_P (XEXP (x, 0))
2032         && bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict)
2033         && (GET_CODE (XEXP (x, 1)) == UNSPEC
2034             || (GET_CODE (XEXP (x, 1)) == CONST_INT
2035                 && bfin_valid_add (mode, INTVAL (XEXP (x, 1))))))
2036       return true;
2037     break;
2038   case POST_INC:
2039   case POST_DEC:
2040     if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
2041         && REG_P (XEXP (x, 0))
2042         && bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict))
2043       return true;
2044   case PRE_DEC:
2045     if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
2046         && XEXP (x, 0) == stack_pointer_rtx
2047         && REG_P (XEXP (x, 0))
2048         && bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict))
2049       return true;
2050     break;
2051   default:
2052     break;
2053   }
2054   return false;
2055 }
2056
2057 static bool
2058 bfin_rtx_costs (rtx x, int code, int outer_code, int *total)
2059 {
2060   int cost2 = COSTS_N_INSNS (1);
2061
2062   switch (code)
2063     {
2064     case CONST_INT:
2065       if (outer_code == SET || outer_code == PLUS)
2066         *total = CONST_7BIT_IMM_P (INTVAL (x)) ? 0 : cost2;
2067       else if (outer_code == AND)
2068         *total = log2constp (~INTVAL (x)) ? 0 : cost2;
2069       else if (outer_code == LE || outer_code == LT || outer_code == EQ)
2070         *total = (INTVAL (x) >= -4 && INTVAL (x) <= 3) ? 0 : cost2;
2071       else if (outer_code == LEU || outer_code == LTU)
2072         *total = (INTVAL (x) >= 0 && INTVAL (x) <= 7) ? 0 : cost2;
2073       else if (outer_code == MULT)
2074         *total = (INTVAL (x) == 2 || INTVAL (x) == 4) ? 0 : cost2;
2075       else if (outer_code == ASHIFT && (INTVAL (x) == 1 || INTVAL (x) == 2))
2076         *total = 0;
2077       else if (outer_code == ASHIFT || outer_code == ASHIFTRT
2078                || outer_code == LSHIFTRT)
2079         *total = (INTVAL (x) >= 0 && INTVAL (x) <= 31) ? 0 : cost2;
2080       else if (outer_code == IOR || outer_code == XOR)
2081         *total = (INTVAL (x) & (INTVAL (x) - 1)) == 0 ? 0 : cost2;
2082       else
2083         *total = cost2;
2084       return true;
2085
2086     case CONST:
2087     case LABEL_REF:
2088     case SYMBOL_REF:
2089     case CONST_DOUBLE:
2090       *total = COSTS_N_INSNS (2);
2091       return true;
2092
2093     case PLUS:
2094       if (GET_MODE (x) == Pmode)
2095         {
2096           if (GET_CODE (XEXP (x, 0)) == MULT
2097               && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2098             {
2099               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
2100               if (val == 2 || val == 4)
2101                 {
2102                   *total = cost2;
2103                   *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code);
2104                   *total += rtx_cost (XEXP (x, 1), outer_code);
2105                   return true;
2106                 }
2107             }
2108         }
2109
2110       /* fall through */
2111
2112     case MINUS:
2113     case ASHIFT: 
2114     case ASHIFTRT:
2115     case LSHIFTRT:
2116       if (GET_MODE (x) == DImode)
2117         *total = 6 * cost2;
2118       return false;
2119           
2120     case AND:
2121     case IOR:
2122     case XOR:
2123       if (GET_MODE (x) == DImode)
2124         *total = 2 * cost2;
2125       return false;
2126
2127     case MULT:
2128       if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD)
2129         *total = COSTS_N_INSNS (3);
2130       return false;
2131
2132     default:
2133       return false;
2134     }
2135 }
2136
2137 static void
2138 bfin_internal_label (FILE *stream, const char *prefix, unsigned long num)
2139 {
2140   fprintf (stream, "%s%s$%ld:\n", LOCAL_LABEL_PREFIX, prefix, num);
2141 }
2142 \f
2143 /* Used for communication between {push,pop}_multiple_operation (which
2144    we use not only as a predicate) and the corresponding output functions.  */
2145 static int first_preg_to_save, first_dreg_to_save;
2146
2147 int
2148 push_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2149 {
2150   int lastdreg = 8, lastpreg = 6;
2151   int i, group;
2152
2153   first_preg_to_save = lastpreg;
2154   first_dreg_to_save = lastdreg;
2155   for (i = 1, group = 0; i < XVECLEN (op, 0) - 1; i++)
2156     {
2157       rtx t = XVECEXP (op, 0, i);
2158       rtx src, dest;
2159       int regno;
2160
2161       if (GET_CODE (t) != SET)
2162         return 0;
2163
2164       src = SET_SRC (t);
2165       dest = SET_DEST (t);
2166       if (GET_CODE (dest) != MEM || ! REG_P (src))
2167         return 0;
2168       dest = XEXP (dest, 0);
2169       if (GET_CODE (dest) != PLUS
2170           || ! REG_P (XEXP (dest, 0))
2171           || REGNO (XEXP (dest, 0)) != REG_SP
2172           || GET_CODE (XEXP (dest, 1)) != CONST_INT
2173           || INTVAL (XEXP (dest, 1)) != -i * 4)
2174         return 0;
2175
2176       regno = REGNO (src);
2177       if (group == 0)
2178         {
2179           if (D_REGNO_P (regno))
2180             {
2181               group = 1;
2182               first_dreg_to_save = lastdreg = regno - REG_R0;
2183             }
2184           else if (regno >= REG_P0 && regno <= REG_P7)
2185             {
2186               group = 2;
2187               first_preg_to_save = lastpreg = regno - REG_P0;
2188             }
2189           else
2190             return 0;
2191
2192           continue;
2193         }
2194
2195       if (group == 1)
2196         {
2197           if (regno >= REG_P0 && regno <= REG_P7)
2198             {
2199               group = 2;
2200               first_preg_to_save = lastpreg = regno - REG_P0;
2201             }
2202           else if (regno != REG_R0 + lastdreg + 1)
2203             return 0;
2204           else
2205             lastdreg++;
2206         }
2207       else if (group == 2)
2208         {
2209           if (regno != REG_P0 + lastpreg + 1)
2210             return 0;
2211           lastpreg++;
2212         }
2213     }
2214   return 1;
2215 }
2216
2217 int
2218 pop_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2219 {
2220   int lastdreg = 8, lastpreg = 6;
2221   int i, group;
2222
2223   for (i = 1, group = 0; i < XVECLEN (op, 0); i++)
2224     {
2225       rtx t = XVECEXP (op, 0, i);
2226       rtx src, dest;
2227       int regno;
2228
2229       if (GET_CODE (t) != SET)
2230         return 0;
2231
2232       src = SET_SRC (t);
2233       dest = SET_DEST (t);
2234       if (GET_CODE (src) != MEM || ! REG_P (dest))
2235         return 0;
2236       src = XEXP (src, 0);
2237
2238       if (i == 1)
2239         {
2240           if (! REG_P (src) || REGNO (src) != REG_SP)
2241             return 0;
2242         }
2243       else if (GET_CODE (src) != PLUS
2244                || ! REG_P (XEXP (src, 0))
2245                || REGNO (XEXP (src, 0)) != REG_SP
2246                || GET_CODE (XEXP (src, 1)) != CONST_INT
2247                || INTVAL (XEXP (src, 1)) != (i - 1) * 4)
2248         return 0;
2249
2250       regno = REGNO (dest);
2251       if (group == 0)
2252         {
2253           if (regno == REG_R7)
2254             {
2255               group = 1;
2256               lastdreg = 7;
2257             }
2258           else if (regno != REG_P0 + lastpreg - 1)
2259             return 0;
2260           else
2261             lastpreg--;
2262         }
2263       else if (group == 1)
2264         {
2265           if (regno != REG_R0 + lastdreg - 1)
2266             return 0;
2267           else
2268             lastdreg--;
2269         }
2270     }
2271   first_dreg_to_save = lastdreg;
2272   first_preg_to_save = lastpreg;
2273   return 1;
2274 }
2275
2276 /* Emit assembly code for one multi-register push described by INSN, with
2277    operands in OPERANDS.  */
2278
2279 void
2280 output_push_multiple (rtx insn, rtx *operands)
2281 {
2282   char buf[80];
2283   int ok;
2284   
2285   /* Validate the insn again, and compute first_[dp]reg_to_save. */
2286   ok = push_multiple_operation (PATTERN (insn), VOIDmode);
2287   gcc_assert (ok);
2288   
2289   if (first_dreg_to_save == 8)
2290     sprintf (buf, "[--sp] = ( p5:%d );\n", first_preg_to_save);
2291   else if (first_preg_to_save == 6)
2292     sprintf (buf, "[--sp] = ( r7:%d );\n", first_dreg_to_save);
2293   else
2294     sprintf (buf, "[--sp] = ( r7:%d, p5:%d );\n",
2295              first_dreg_to_save, first_preg_to_save);
2296
2297   output_asm_insn (buf, operands);
2298 }
2299
2300 /* Emit assembly code for one multi-register pop described by INSN, with
2301    operands in OPERANDS.  */
2302
2303 void
2304 output_pop_multiple (rtx insn, rtx *operands)
2305 {
2306   char buf[80];
2307   int ok;
2308   
2309   /* Validate the insn again, and compute first_[dp]reg_to_save. */
2310   ok = pop_multiple_operation (PATTERN (insn), VOIDmode);
2311   gcc_assert (ok);
2312
2313   if (first_dreg_to_save == 8)
2314     sprintf (buf, "( p5:%d ) = [sp++];\n", first_preg_to_save);
2315   else if (first_preg_to_save == 6)
2316     sprintf (buf, "( r7:%d ) = [sp++];\n", first_dreg_to_save);
2317   else
2318     sprintf (buf, "( r7:%d, p5:%d ) = [sp++];\n",
2319              first_dreg_to_save, first_preg_to_save);
2320
2321   output_asm_insn (buf, operands);
2322 }
2323
2324 /* Adjust DST and SRC by OFFSET bytes, and generate one move in mode MODE.  */
2325
2326 static void
2327 single_move_for_strmov (rtx dst, rtx src, enum machine_mode mode, HOST_WIDE_INT offset)
2328 {
2329   rtx scratch = gen_reg_rtx (mode);
2330   rtx srcmem, dstmem;
2331
2332   srcmem = adjust_address_nv (src, mode, offset);
2333   dstmem = adjust_address_nv (dst, mode, offset);
2334   emit_move_insn (scratch, srcmem);
2335   emit_move_insn (dstmem, scratch);
2336 }
2337
2338 /* Expand a string move operation of COUNT_EXP bytes from SRC to DST, with
2339    alignment ALIGN_EXP.  Return true if successful, false if we should fall
2340    back on a different method.  */
2341
2342 bool
2343 bfin_expand_strmov (rtx dst, rtx src, rtx count_exp, rtx align_exp)
2344 {
2345   rtx srcreg, destreg, countreg;
2346   HOST_WIDE_INT align = 0;
2347   unsigned HOST_WIDE_INT count = 0;
2348
2349   if (GET_CODE (align_exp) == CONST_INT)
2350     align = INTVAL (align_exp);
2351   if (GET_CODE (count_exp) == CONST_INT)
2352     {
2353       count = INTVAL (count_exp);
2354 #if 0
2355       if (!TARGET_INLINE_ALL_STRINGOPS && count > 64)
2356         return false;
2357 #endif
2358     }
2359
2360   /* If optimizing for size, only do single copies inline.  */
2361   if (optimize_size)
2362     {
2363       if (count == 2 && align < 2)
2364         return false;
2365       if (count == 4 && align < 4)
2366         return false;
2367       if (count != 1 && count != 2 && count != 4)
2368         return false;
2369     }
2370   if (align < 2 && count != 1)
2371     return false;
2372
2373   destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
2374   if (destreg != XEXP (dst, 0))
2375     dst = replace_equiv_address_nv (dst, destreg);
2376   srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
2377   if (srcreg != XEXP (src, 0))
2378     src = replace_equiv_address_nv (src, srcreg);
2379
2380   if (count != 0 && align >= 2)
2381     {
2382       unsigned HOST_WIDE_INT offset = 0;
2383
2384       if (align >= 4)
2385         {
2386           if ((count & ~3) == 4)
2387             {
2388               single_move_for_strmov (dst, src, SImode, offset);
2389               offset = 4;
2390             }
2391           else if (count & ~3)
2392             {
2393               HOST_WIDE_INT new_count = ((count >> 2) & 0x3fffffff) - 1;
2394               countreg = copy_to_mode_reg (Pmode, GEN_INT (new_count));
2395
2396               emit_insn (gen_rep_movsi (destreg, srcreg, countreg, destreg, srcreg));
2397             }
2398         }
2399       else
2400         {
2401           if ((count & ~1) == 2)
2402             {
2403               single_move_for_strmov (dst, src, HImode, offset);
2404               offset = 2;
2405             }
2406           else if (count & ~1)
2407             {
2408               HOST_WIDE_INT new_count = ((count >> 1) & 0x7fffffff) - 1;
2409               countreg = copy_to_mode_reg (Pmode, GEN_INT (new_count));
2410
2411               emit_insn (gen_rep_movhi (destreg, srcreg, countreg, destreg, srcreg));
2412             }
2413         }
2414       if (count & 2)
2415         {
2416           single_move_for_strmov (dst, src, HImode, offset);
2417           offset += 2;
2418         }
2419       if (count & 1)
2420         {
2421           single_move_for_strmov (dst, src, QImode, offset);
2422         }
2423       return true;
2424     }
2425   return false;
2426 }
2427
2428 \f
2429 static int
2430 bfin_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
2431 {
2432   enum attr_type insn_type, dep_insn_type;
2433   int dep_insn_code_number;
2434
2435   /* Anti and output dependencies have zero cost.  */
2436   if (REG_NOTE_KIND (link) != 0)
2437     return 0;
2438
2439   dep_insn_code_number = recog_memoized (dep_insn);
2440
2441   /* If we can't recognize the insns, we can't really do anything.  */
2442   if (dep_insn_code_number < 0 || recog_memoized (insn) < 0)
2443     return cost;
2444
2445   insn_type = get_attr_type (insn);
2446   dep_insn_type = get_attr_type (dep_insn);
2447
2448   if (dep_insn_type == TYPE_MOVE || dep_insn_type == TYPE_MCLD)
2449     {
2450       rtx pat = PATTERN (dep_insn);
2451       rtx dest = SET_DEST (pat);
2452       rtx src = SET_SRC (pat);
2453       if (! ADDRESS_REGNO_P (REGNO (dest)) || ! D_REGNO_P (REGNO (src)))
2454         return cost;
2455       return cost + (dep_insn_type == TYPE_MOVE ? 4 : 3);
2456     }
2457
2458   return cost;
2459 }
2460 \f
2461 /* We use the machine specific reorg pass for emitting CSYNC instructions
2462    after conditional branches as needed.
2463
2464    The Blackfin is unusual in that a code sequence like
2465      if cc jump label
2466      r0 = (p0)
2467    may speculatively perform the load even if the condition isn't true.  This
2468    happens for a branch that is predicted not taken, because the pipeline
2469    isn't flushed or stalled, so the early stages of the following instructions,
2470    which perform the memory reference, are allowed to execute before the
2471    jump condition is evaluated.
2472    Therefore, we must insert additional instructions in all places where this
2473    could lead to incorrect behaviour.  The manual recommends CSYNC, while
2474    VDSP seems to use NOPs (even though its corresponding compiler option is
2475    named CSYNC).
2476
2477    When optimizing for speed, we emit NOPs, which seems faster than a CSYNC.
2478    When optimizing for size, we turn the branch into a predicted taken one.
2479    This may be slower due to mispredicts, but saves code size.  */
2480
2481 static void
2482 bfin_reorg (void)
2483 {
2484   rtx insn, last_condjump = NULL_RTX;
2485   int cycles_since_jump = INT_MAX;
2486
2487   if (! TARGET_CSYNC)
2488     return;
2489
2490   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2491     {
2492       rtx pat;
2493
2494       if (NOTE_P (insn) || BARRIER_P (insn) || LABEL_P (insn))
2495         continue;
2496
2497       pat = PATTERN (insn);
2498       if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
2499           || GET_CODE (pat) == ASM_INPUT || GET_CODE (pat) == ADDR_VEC
2500           || GET_CODE (pat) == ADDR_DIFF_VEC || asm_noperands (pat) >= 0)
2501         continue;
2502
2503       if (JUMP_P (insn))
2504         {
2505           if (any_condjump_p (insn)
2506               && ! cbranch_predicted_taken_p (insn))
2507             {
2508               last_condjump = insn;
2509               cycles_since_jump = 0;
2510             }
2511           else
2512             cycles_since_jump = INT_MAX;
2513         }
2514       else if (INSN_P (insn))
2515         {
2516           enum attr_type type = get_attr_type (insn);
2517           if (cycles_since_jump < INT_MAX)
2518             cycles_since_jump++;
2519
2520           if (type == TYPE_MCLD && cycles_since_jump < 3)
2521             {
2522               rtx pat;
2523
2524               pat = single_set (insn);
2525               if (may_trap_p (SET_SRC (pat)))
2526                 {
2527                   int num_clobbers;
2528                   rtx *op = recog_data.operand;
2529
2530                   extract_insn (last_condjump);
2531                   if (optimize_size)
2532                     pat = gen_cbranch_predicted_taken (op[0], op[1], op[2],
2533                                                        op[3]);
2534                   else
2535                     pat = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
2536                                                  GEN_INT (3 - cycles_since_jump));
2537                   PATTERN (last_condjump) = pat;
2538                   INSN_CODE (last_condjump) = recog (pat, insn, &num_clobbers);
2539                   cycles_since_jump = INT_MAX;
2540                 }
2541             }
2542         }
2543     }
2544 }
2545 \f
2546 /* Handle interrupt_handler, exception_handler and nmi_handler function
2547    attributes; arguments as in struct attribute_spec.handler.  */
2548
2549 static tree
2550 handle_int_attribute (tree *node, tree name,
2551                       tree args ATTRIBUTE_UNUSED,
2552                       int flags ATTRIBUTE_UNUSED,
2553                       bool *no_add_attrs)
2554 {
2555   tree x = *node;
2556   if (TREE_CODE (x) == FUNCTION_DECL)
2557     x = TREE_TYPE (x);
2558
2559   if (TREE_CODE (x) != FUNCTION_TYPE)
2560     {
2561       warning (OPT_Wattributes, "%qs attribute only applies to functions",
2562                IDENTIFIER_POINTER (name));
2563       *no_add_attrs = true;
2564     }
2565   else if (funkind (x) != SUBROUTINE)
2566     error ("multiple function type attributes specified");
2567
2568   return NULL_TREE;
2569 }
2570
2571 /* Return 0 if the attributes for two types are incompatible, 1 if they
2572    are compatible, and 2 if they are nearly compatible (which causes a
2573    warning to be generated).  */
2574
2575 static int
2576 bfin_comp_type_attributes (tree type1, tree type2)
2577 {
2578   e_funkind kind1, kind2;
2579
2580   if (TREE_CODE (type1) != FUNCTION_TYPE)
2581     return 1;
2582
2583   kind1 = funkind (type1);
2584   kind2 = funkind (type2);
2585
2586   if (kind1 != kind2)
2587     return 0;
2588   
2589   /*  Check for mismatched modifiers */
2590   if (!lookup_attribute ("nesting", TYPE_ATTRIBUTES (type1))
2591       != !lookup_attribute ("nesting", TYPE_ATTRIBUTES (type2)))
2592     return 0;
2593
2594   if (!lookup_attribute ("saveall", TYPE_ATTRIBUTES (type1))
2595       != !lookup_attribute ("saveall", TYPE_ATTRIBUTES (type2)))
2596     return 0;
2597
2598   if (!lookup_attribute ("kspisusp", TYPE_ATTRIBUTES (type1))
2599       != !lookup_attribute ("kspisusp", TYPE_ATTRIBUTES (type2)))
2600     return 0;
2601
2602   return 1;
2603 }
2604
2605 /* Table of valid machine attributes.  */
2606 const struct attribute_spec bfin_attribute_table[] =
2607 {
2608   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
2609   { "interrupt_handler", 0, 0, false, true,  true, handle_int_attribute },
2610   { "exception_handler", 0, 0, false, true,  true, handle_int_attribute },
2611   { "nmi_handler", 0, 0, false, true,  true, handle_int_attribute },
2612   { "nesting", 0, 0, false, true,  true, NULL },
2613   { "kspisusp", 0, 0, false, true,  true, NULL },
2614   { "saveall", 0, 0, false, true,  true, NULL },
2615   { NULL, 0, 0, false, false, false, NULL }
2616 };
2617 \f
2618 /* Output the assembler code for a thunk function.  THUNK_DECL is the
2619    declaration for the thunk function itself, FUNCTION is the decl for
2620    the target function.  DELTA is an immediate constant offset to be
2621    added to THIS.  If VCALL_OFFSET is nonzero, the word at
2622    *(*this + vcall_offset) should be added to THIS.  */
2623
2624 static void
2625 bfin_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
2626                       tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
2627                       HOST_WIDE_INT vcall_offset, tree function)
2628 {
2629   rtx xops[3];
2630   /* The this parameter is passed as the first argument.  */
2631   rtx this = gen_rtx_REG (Pmode, REG_R0);
2632
2633   /* Adjust the this parameter by a fixed constant.  */
2634   if (delta)
2635     {
2636       xops[1] = this;
2637       if (delta >= -64 && delta <= 63)
2638         {
2639           xops[0] = GEN_INT (delta);
2640           output_asm_insn ("%1 += %0;", xops);
2641         }
2642       else if (delta >= -128 && delta < -64)
2643         {
2644           xops[0] = GEN_INT (delta + 64);
2645           output_asm_insn ("%1 += -64; %1 += %0;", xops);
2646         }
2647       else if (delta > 63 && delta <= 126)
2648         {
2649           xops[0] = GEN_INT (delta - 63);
2650           output_asm_insn ("%1 += 63; %1 += %0;", xops);
2651         }
2652       else
2653         {
2654           xops[0] = GEN_INT (delta);
2655           output_asm_insn ("r3.l = %h0; r3.h = %d0; %1 = %1 + r3;", xops);
2656         }
2657     }
2658
2659   /* Adjust the this parameter by a value stored in the vtable.  */
2660   if (vcall_offset)
2661     {
2662       rtx p2tmp = gen_rtx_REG (Pmode, REG_P2);
2663       rtx tmp = gen_rtx_REG (Pmode, REG_R2);
2664
2665       xops[1] = tmp;
2666       xops[2] = p2tmp;
2667       output_asm_insn ("%2 = r0; %2 = [%2];", xops);
2668
2669       /* Adjust the this parameter.  */
2670       xops[0] = gen_rtx_MEM (Pmode, plus_constant (p2tmp, vcall_offset));
2671       if (!memory_operand (xops[0], Pmode))
2672         {
2673           rtx tmp2 = gen_rtx_REG (Pmode, REG_P1);
2674           xops[0] = GEN_INT (vcall_offset);
2675           xops[1] = tmp2;
2676           output_asm_insn ("%h1 = %h0; %d1 = %d0; %2 = %2 + %1", xops);
2677           xops[0] = gen_rtx_MEM (Pmode, p2tmp);
2678         }
2679       xops[2] = this;
2680       output_asm_insn ("%1 = %0; %2 = %2 + %1;", xops);
2681     }
2682
2683   xops[0] = XEXP (DECL_RTL (function), 0);
2684   if (1 || !flag_pic || (*targetm.binds_local_p) (function))
2685     output_asm_insn ("jump.l\t%P0", xops);
2686 }
2687 \f
2688 #undef TARGET_ASM_GLOBALIZE_LABEL
2689 #define TARGET_ASM_GLOBALIZE_LABEL bfin_globalize_label 
2690
2691 #undef TARGET_ASM_FILE_START
2692 #define TARGET_ASM_FILE_START output_file_start
2693
2694 #undef TARGET_ATTRIBUTE_TABLE
2695 #define TARGET_ATTRIBUTE_TABLE bfin_attribute_table
2696
2697 #undef TARGET_COMP_TYPE_ATTRIBUTES
2698 #define TARGET_COMP_TYPE_ATTRIBUTES bfin_comp_type_attributes
2699
2700 #undef TARGET_RTX_COSTS
2701 #define TARGET_RTX_COSTS bfin_rtx_costs
2702
2703 #undef  TARGET_ADDRESS_COST
2704 #define TARGET_ADDRESS_COST bfin_address_cost
2705
2706 #undef TARGET_ASM_INTERNAL_LABEL
2707 #define TARGET_ASM_INTERNAL_LABEL bfin_internal_label
2708
2709 #undef TARGET_MACHINE_DEPENDENT_REORG
2710 #define TARGET_MACHINE_DEPENDENT_REORG bfin_reorg
2711
2712 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
2713 #define TARGET_FUNCTION_OK_FOR_SIBCALL bfin_function_ok_for_sibcall
2714
2715 #undef TARGET_ASM_OUTPUT_MI_THUNK
2716 #define TARGET_ASM_OUTPUT_MI_THUNK bfin_output_mi_thunk
2717 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
2718 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
2719
2720 #undef TARGET_SCHED_ADJUST_COST
2721 #define TARGET_SCHED_ADJUST_COST bfin_adjust_cost
2722
2723 #undef TARGET_PROMOTE_PROTOTYPES
2724 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
2725 #undef TARGET_PROMOTE_FUNCTION_ARGS
2726 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
2727 #undef TARGET_PROMOTE_FUNCTION_RETURN
2728 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
2729
2730 #undef TARGET_ARG_PARTIAL_BYTES
2731 #define TARGET_ARG_PARTIAL_BYTES bfin_arg_partial_bytes
2732
2733 #undef TARGET_PASS_BY_REFERENCE
2734 #define TARGET_PASS_BY_REFERENCE bfin_pass_by_reference
2735
2736 #undef TARGET_SETUP_INCOMING_VARARGS
2737 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
2738
2739 #undef TARGET_STRUCT_VALUE_RTX
2740 #define TARGET_STRUCT_VALUE_RTX bfin_struct_value_rtx
2741
2742 #undef TARGET_VECTOR_MODE_SUPPORTED_P
2743 #define TARGET_VECTOR_MODE_SUPPORTED_P bfin_vector_mode_supported_p
2744
2745 #undef TARGET_HANDLE_OPTION
2746 #define TARGET_HANDLE_OPTION bfin_handle_option
2747
2748 struct gcc_target targetm = TARGET_INITIALIZER;