OSDN Git Service

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