OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / bfin / bfin.c
1 /* The Blackfin code generation auxiliary output file.
2    Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
3    Contributed by Analog Devices.
4
5    This file is part of GCC.
6
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 3, or (at your
10    option) any later version.
11
12    GCC is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING3.  If not see
19    <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "insn-codes.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 "optabs.h"
46 #include "ggc.h"
47 #include "integrate.h"
48 #include "cgraph.h"
49 #include "langhooks.h"
50 #include "bfin-protos.h"
51 #include "tm-preds.h"
52 #include "tm-constrs.h"
53 #include "gt-bfin.h"
54 #include "basic-block.h"
55 #include "cfglayout.h"
56 #include "timevar.h"
57 #include "df.h"
58
59 /* A C structure for machine-specific, per-function data.
60    This is added to the cfun structure.  */
61 struct GTY(()) machine_function
62 {
63   /* Set if we are notified by the doloop pass that a hardware loop
64      was created.  */
65   int has_hardware_loops;
66
67   /* Set if we create a memcpy pattern that uses loop registers.  */
68   int has_loopreg_clobber;
69 };
70
71 /* RTX for condition code flag register and RETS register */
72 extern GTY(()) rtx bfin_cc_rtx;
73 extern GTY(()) rtx bfin_rets_rtx;
74 rtx bfin_cc_rtx, bfin_rets_rtx;
75
76 int max_arg_registers = 0;
77
78 /* Arrays used when emitting register names.  */
79 const char *short_reg_names[]  =  SHORT_REGISTER_NAMES;
80 const char *high_reg_names[]   =  HIGH_REGISTER_NAMES;
81 const char *dregs_pair_names[] =  DREGS_PAIR_NAMES;
82 const char *byte_reg_names[]   =  BYTE_REGISTER_NAMES;
83
84 static int arg_regs[] = FUNCTION_ARG_REGISTERS;
85 static int ret_regs[] = FUNCTION_RETURN_REGISTERS;
86
87 /* Nonzero if -mshared-library-id was given.  */
88 static int bfin_lib_id_given;
89
90 /* Nonzero if -fschedule-insns2 was given.  We override it and
91    call the scheduler ourselves during reorg.  */
92 static int bfin_flag_schedule_insns2;
93
94 /* Determines whether we run variable tracking in machine dependent
95    reorganization.  */
96 static int bfin_flag_var_tracking;
97
98 /* -mcpu support */
99 bfin_cpu_t bfin_cpu_type = BFIN_CPU_UNKNOWN;
100
101 /* -msi-revision support. There are three special values:
102    -1      -msi-revision=none.
103    0xffff  -msi-revision=any.  */
104 int bfin_si_revision;
105
106 /* The workarounds enabled */
107 unsigned int bfin_workarounds = 0;
108
109 struct bfin_cpu
110 {
111   const char *name;
112   bfin_cpu_t type;
113   int si_revision;
114   unsigned int workarounds;
115 };
116
117 struct bfin_cpu bfin_cpus[] =
118 {
119   {"bf512", BFIN_CPU_BF512, 0x0000,
120    WA_SPECULATIVE_LOADS | WA_05000074},
121
122   {"bf514", BFIN_CPU_BF514, 0x0000,
123    WA_SPECULATIVE_LOADS | WA_05000074},
124
125   {"bf516", BFIN_CPU_BF516, 0x0000,
126    WA_SPECULATIVE_LOADS | WA_05000074},
127
128   {"bf518", BFIN_CPU_BF518, 0x0000,
129    WA_SPECULATIVE_LOADS | WA_05000074},
130
131   {"bf522", BFIN_CPU_BF522, 0x0002,
132    WA_SPECULATIVE_LOADS | WA_05000074},
133   {"bf522", BFIN_CPU_BF522, 0x0001,
134    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
135   {"bf522", BFIN_CPU_BF522, 0x0000,
136    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
137
138   {"bf523", BFIN_CPU_BF523, 0x0002,
139    WA_SPECULATIVE_LOADS | WA_05000074},
140   {"bf523", BFIN_CPU_BF523, 0x0001,
141    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
142   {"bf523", BFIN_CPU_BF523, 0x0000,
143    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
144
145   {"bf524", BFIN_CPU_BF524, 0x0002,
146    WA_SPECULATIVE_LOADS | WA_05000074},
147   {"bf524", BFIN_CPU_BF524, 0x0001,
148    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
149   {"bf524", BFIN_CPU_BF524, 0x0000,
150    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
151
152   {"bf525", BFIN_CPU_BF525, 0x0002,
153    WA_SPECULATIVE_LOADS | WA_05000074},
154   {"bf525", BFIN_CPU_BF525, 0x0001,
155    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
156   {"bf525", BFIN_CPU_BF525, 0x0000,
157    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
158
159   {"bf526", BFIN_CPU_BF526, 0x0002,
160    WA_SPECULATIVE_LOADS | WA_05000074},
161   {"bf526", BFIN_CPU_BF526, 0x0001,
162    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
163   {"bf526", BFIN_CPU_BF526, 0x0000,
164    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
165
166   {"bf527", BFIN_CPU_BF527, 0x0002,
167    WA_SPECULATIVE_LOADS | WA_05000074},
168   {"bf527", BFIN_CPU_BF527, 0x0001,
169    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
170   {"bf527", BFIN_CPU_BF527, 0x0000,
171    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
172
173   {"bf531", BFIN_CPU_BF531, 0x0006,
174    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
175   {"bf531", BFIN_CPU_BF531, 0x0005,
176    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
177    | WA_LOAD_LCREGS | WA_05000074},
178   {"bf531", BFIN_CPU_BF531, 0x0004,
179    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
180    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
181    | WA_05000074},
182   {"bf531", BFIN_CPU_BF531, 0x0003,
183    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
184    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
185    | WA_05000074},
186
187   {"bf532", BFIN_CPU_BF532, 0x0006,
188    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
189   {"bf532", BFIN_CPU_BF532, 0x0005,
190    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
191    | WA_LOAD_LCREGS | WA_05000074},
192   {"bf532", BFIN_CPU_BF532, 0x0004,
193    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
194    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
195    | WA_05000074},
196   {"bf532", BFIN_CPU_BF532, 0x0003,
197    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
198    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
199    | WA_05000074},
200
201   {"bf533", BFIN_CPU_BF533, 0x0006,
202    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
203   {"bf533", BFIN_CPU_BF533, 0x0005,
204    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
205    | WA_LOAD_LCREGS | WA_05000074},
206   {"bf533", BFIN_CPU_BF533, 0x0004,
207    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
208    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
209    | WA_05000074},
210   {"bf533", BFIN_CPU_BF533, 0x0003,
211    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
212    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
213    | WA_05000074},
214
215   {"bf534", BFIN_CPU_BF534, 0x0003,
216    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
217   {"bf534", BFIN_CPU_BF534, 0x0002,
218    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
219    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
220    | WA_05000074},
221   {"bf534", BFIN_CPU_BF534, 0x0001,
222    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
223    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
224    | WA_05000074},
225
226   {"bf536", BFIN_CPU_BF536, 0x0003,
227    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
228   {"bf536", BFIN_CPU_BF536, 0x0002,
229    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
230    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
231    | WA_05000074},
232   {"bf536", BFIN_CPU_BF536, 0x0001,
233    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
234    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
235    | WA_05000074},
236
237   {"bf537", BFIN_CPU_BF537, 0x0003,
238    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
239   {"bf537", BFIN_CPU_BF537, 0x0002,
240    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
241    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
242    | WA_05000074},
243   {"bf537", BFIN_CPU_BF537, 0x0001,
244    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
245    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
246    | WA_05000074},
247
248   {"bf538", BFIN_CPU_BF538, 0x0005,
249    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
250   {"bf538", BFIN_CPU_BF538, 0x0004,
251    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
252   {"bf538", BFIN_CPU_BF538, 0x0003,
253    WA_SPECULATIVE_LOADS | WA_RETS
254    | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
255   {"bf538", BFIN_CPU_BF538, 0x0002,
256    WA_SPECULATIVE_LOADS | WA_RETS
257    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
258    | WA_05000074},
259
260   {"bf539", BFIN_CPU_BF539, 0x0005,
261    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
262   {"bf539", BFIN_CPU_BF539, 0x0004,
263    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
264   {"bf539", BFIN_CPU_BF539, 0x0003,
265    WA_SPECULATIVE_LOADS | WA_RETS
266    | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
267   {"bf539", BFIN_CPU_BF539, 0x0002,
268    WA_SPECULATIVE_LOADS | WA_RETS
269    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
270    | WA_05000074},
271
272   {"bf542m", BFIN_CPU_BF542M, 0x0003,
273    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
274
275   {"bf542", BFIN_CPU_BF542, 0x0002,
276    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
277   {"bf542", BFIN_CPU_BF542, 0x0001,
278    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
279   {"bf542", BFIN_CPU_BF542, 0x0000,
280    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
281    | WA_05000074},
282
283   {"bf544m", BFIN_CPU_BF544M, 0x0003,
284    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
285
286   {"bf544", BFIN_CPU_BF544, 0x0002,
287    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
288   {"bf544", BFIN_CPU_BF544, 0x0001,
289    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
290   {"bf544", BFIN_CPU_BF544, 0x0000,
291    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
292    | WA_05000074},
293
294   {"bf547m", BFIN_CPU_BF547M, 0x0003,
295    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
296
297   {"bf547", BFIN_CPU_BF547, 0x0002,
298    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
299   {"bf547", BFIN_CPU_BF547, 0x0001,
300    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
301   {"bf547", BFIN_CPU_BF547, 0x0000,
302    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
303    | WA_05000074},
304
305   {"bf548m", BFIN_CPU_BF548M, 0x0003,
306    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
307
308   {"bf548", BFIN_CPU_BF548, 0x0002,
309    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
310   {"bf548", BFIN_CPU_BF548, 0x0001,
311    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
312   {"bf548", BFIN_CPU_BF548, 0x0000,
313    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
314    | WA_05000074},
315
316   {"bf549m", BFIN_CPU_BF549M, 0x0003,
317    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
318
319   {"bf549", BFIN_CPU_BF549, 0x0002,
320    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
321   {"bf549", BFIN_CPU_BF549, 0x0001,
322    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
323   {"bf549", BFIN_CPU_BF549, 0x0000,
324    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
325    | WA_05000074},
326
327   {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS
328    | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
329   {"bf561", BFIN_CPU_BF561, 0x0003,
330    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
331    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
332    | WA_05000074},
333   {"bf561", BFIN_CPU_BF561, 0x0002,
334    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
335    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
336    | WA_05000074},
337
338   {NULL, 0, 0, 0}
339 };
340
341 int splitting_for_sched, splitting_loops;
342
343 static void
344 bfin_globalize_label (FILE *stream, const char *name)
345 {
346   fputs (".global ", stream);
347   assemble_name (stream, name);
348   fputc (';',stream);
349   fputc ('\n',stream);
350 }
351
352 static void 
353 output_file_start (void) 
354 {
355   FILE *file = asm_out_file;
356   int i;
357
358   /* Variable tracking should be run after all optimizations which change order
359      of insns.  It also needs a valid CFG.  This can't be done in
360      override_options, because flag_var_tracking is finalized after
361      that.  */
362   bfin_flag_var_tracking = flag_var_tracking;
363   flag_var_tracking = 0;
364
365   fprintf (file, ".file \"%s\";\n", input_filename);
366   
367   for (i = 0; arg_regs[i] >= 0; i++)
368     ;
369   max_arg_registers = i;        /* how many arg reg used  */
370 }
371
372 /* Called early in the compilation to conditionally modify
373    fixed_regs/call_used_regs.  */
374
375 void 
376 conditional_register_usage (void)
377 {
378   /* initialize condition code flag register rtx */
379   bfin_cc_rtx = gen_rtx_REG (BImode, REG_CC);
380   bfin_rets_rtx = gen_rtx_REG (Pmode, REG_RETS);
381 }
382
383 /* Examine machine-dependent attributes of function type FUNTYPE and return its
384    type.  See the definition of E_FUNKIND.  */
385
386 static e_funkind
387 funkind (const_tree funtype)
388 {
389   tree attrs = TYPE_ATTRIBUTES (funtype);
390   if (lookup_attribute ("interrupt_handler", attrs))
391     return INTERRUPT_HANDLER;
392   else if (lookup_attribute ("exception_handler", attrs))
393     return EXCPT_HANDLER;
394   else if (lookup_attribute ("nmi_handler", attrs))
395     return NMI_HANDLER;
396   else
397     return SUBROUTINE;
398 }
399 \f
400 /* Legitimize PIC addresses.  If the address is already position-independent,
401    we return ORIG.  Newly generated position-independent addresses go into a
402    reg.  This is REG if nonzero, otherwise we allocate register(s) as
403    necessary.  PICREG is the register holding the pointer to the PIC offset
404    table.  */
405
406 static rtx
407 legitimize_pic_address (rtx orig, rtx reg, rtx picreg)
408 {
409   rtx addr = orig;
410   rtx new_rtx = orig;
411
412   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
413     {
414       int unspec;
415       rtx tmp;
416
417       if (TARGET_ID_SHARED_LIBRARY)
418         unspec = UNSPEC_MOVE_PIC;
419       else if (GET_CODE (addr) == SYMBOL_REF
420                && SYMBOL_REF_FUNCTION_P (addr))
421         unspec = UNSPEC_FUNCDESC_GOT17M4;
422       else
423         unspec = UNSPEC_MOVE_FDPIC;
424
425       if (reg == 0)
426         {
427           gcc_assert (can_create_pseudo_p ());
428           reg = gen_reg_rtx (Pmode);
429         }
430
431       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), unspec);
432       new_rtx = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, picreg, tmp));
433
434       emit_move_insn (reg, new_rtx);
435       if (picreg == pic_offset_table_rtx)
436         crtl->uses_pic_offset_table = 1;
437       return reg;
438     }
439
440   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
441     {
442       rtx base;
443
444       if (GET_CODE (addr) == CONST)
445         {
446           addr = XEXP (addr, 0);
447           gcc_assert (GET_CODE (addr) == PLUS);
448         }
449
450       if (XEXP (addr, 0) == picreg)
451         return orig;
452
453       if (reg == 0)
454         {
455           gcc_assert (can_create_pseudo_p ());
456           reg = gen_reg_rtx (Pmode);
457         }
458
459       base = legitimize_pic_address (XEXP (addr, 0), reg, picreg);
460       addr = legitimize_pic_address (XEXP (addr, 1),
461                                      base == reg ? NULL_RTX : reg,
462                                      picreg);
463
464       if (GET_CODE (addr) == CONST_INT)
465         {
466           gcc_assert (! reload_in_progress && ! reload_completed);
467           addr = force_reg (Pmode, addr);
468         }
469
470       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
471         {
472           base = gen_rtx_PLUS (Pmode, base, XEXP (addr, 0));
473           addr = XEXP (addr, 1);
474         }
475
476       return gen_rtx_PLUS (Pmode, base, addr);
477     }
478
479   return new_rtx;
480 }
481 \f
482 /* Stack frame layout. */
483
484 /* For a given REGNO, determine whether it must be saved in the function
485    prologue.  IS_INTHANDLER specifies whether we're generating a normal
486    prologue or an interrupt/exception one.  */
487 static bool
488 must_save_p (bool is_inthandler, unsigned regno)
489 {
490   if (D_REGNO_P (regno))
491     {
492       bool is_eh_return_reg = false;
493       if (crtl->calls_eh_return)
494         {
495           unsigned j;
496           for (j = 0; ; j++)
497             {
498               unsigned test = EH_RETURN_DATA_REGNO (j);
499               if (test == INVALID_REGNUM)
500                 break;
501               if (test == regno)
502                 is_eh_return_reg = true;
503             }
504         }
505
506       return (is_eh_return_reg
507               || (df_regs_ever_live_p (regno)
508                   && !fixed_regs[regno]
509                   && (is_inthandler || !call_used_regs[regno])));
510     }
511   else if (P_REGNO_P (regno))
512     {
513       return ((df_regs_ever_live_p (regno)
514                && !fixed_regs[regno]
515                && (is_inthandler || !call_used_regs[regno]))
516               || (is_inthandler
517                   && (ENABLE_WA_05000283 || ENABLE_WA_05000315)
518                   && regno == REG_P5)
519               || (!TARGET_FDPIC
520                   && regno == PIC_OFFSET_TABLE_REGNUM
521                   && (crtl->uses_pic_offset_table
522                       || (TARGET_ID_SHARED_LIBRARY && !current_function_is_leaf))));
523     }
524   else
525     return ((is_inthandler || !call_used_regs[regno])
526             && (df_regs_ever_live_p (regno)
527                 || (!leaf_function_p () && call_used_regs[regno])));
528
529 }
530
531 /* Compute the number of DREGS to save with a push_multiple operation.
532    This could include registers that aren't modified in the function,
533    since push_multiple only takes a range of registers.
534    If IS_INTHANDLER, then everything that is live must be saved, even
535    if normally call-clobbered.
536    If CONSECUTIVE, return the number of registers we can save in one
537    instruction with a push/pop multiple instruction.  */
538
539 static int
540 n_dregs_to_save (bool is_inthandler, bool consecutive)
541 {
542   int count = 0;
543   unsigned i;
544
545   for (i = REG_R7 + 1; i-- != REG_R0;)
546     {
547       if (must_save_p (is_inthandler, i))
548         count++;
549       else if (consecutive)
550         return count;
551     }
552   return count;
553 }
554
555 /* Like n_dregs_to_save, but compute number of PREGS to save.  */
556
557 static int
558 n_pregs_to_save (bool is_inthandler, bool consecutive)
559 {
560   int count = 0;
561   unsigned i;
562
563   for (i = REG_P5 + 1; i-- != REG_P0;)
564     if (must_save_p (is_inthandler, i))
565       count++;
566     else if (consecutive)
567       return count;
568   return count;
569 }
570
571 /* Determine if we are going to save the frame pointer in the prologue.  */
572
573 static bool
574 must_save_fp_p (void)
575 {
576   return df_regs_ever_live_p (REG_FP);
577 }
578
579 /* Determine if we are going to save the RETS register.  */
580 static bool
581 must_save_rets_p (void)
582 {
583   return df_regs_ever_live_p (REG_RETS);
584 }
585
586 static bool
587 stack_frame_needed_p (void)
588 {
589   /* EH return puts a new return address into the frame using an
590      address relative to the frame pointer.  */
591   if (crtl->calls_eh_return)
592     return true;
593   return frame_pointer_needed;
594 }
595
596 /* Emit code to save registers in the prologue.  SAVEALL is nonzero if we
597    must save all registers; this is used for interrupt handlers.
598    SPREG contains (reg:SI REG_SP).  IS_INTHANDLER is true if we're doing
599    this for an interrupt (or exception) handler.  */
600
601 static void
602 expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler)
603 {
604   rtx predec1 = gen_rtx_PRE_DEC (SImode, spreg);
605   rtx predec = gen_rtx_MEM (SImode, predec1);
606   int ndregs = saveall ? 8 : n_dregs_to_save (is_inthandler, false);
607   int npregs = saveall ? 6 : n_pregs_to_save (is_inthandler, false);
608   int ndregs_consec = saveall ? 8 : n_dregs_to_save (is_inthandler, true);
609   int npregs_consec = saveall ? 6 : n_pregs_to_save (is_inthandler, true);
610   int dregno, pregno;
611   int total_consec = ndregs_consec + npregs_consec;
612   int i, d_to_save;
613
614   if (saveall || is_inthandler)
615     {
616       rtx insn = emit_move_insn (predec, gen_rtx_REG (SImode, REG_ASTAT));
617
618       RTX_FRAME_RELATED_P (insn) = 1;
619       for (dregno = REG_LT0; dregno <= REG_LB1; dregno++)
620         if (! current_function_is_leaf
621             || cfun->machine->has_hardware_loops
622             || cfun->machine->has_loopreg_clobber
623             || (ENABLE_WA_05000257
624                 && (dregno == REG_LC0 || dregno == REG_LC1)))
625           {
626             insn = emit_move_insn (predec, gen_rtx_REG (SImode, dregno));
627             RTX_FRAME_RELATED_P (insn) = 1;
628           }
629     }
630
631   if (total_consec != 0)
632     {
633       rtx insn;
634       rtx val = GEN_INT (-total_consec * 4);
635       rtx pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_consec + 2));
636
637       XVECEXP (pat, 0, 0) = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, val),
638                                             UNSPEC_PUSH_MULTIPLE);
639       XVECEXP (pat, 0, total_consec + 1) = gen_rtx_SET (VOIDmode, spreg,
640                                                         gen_rtx_PLUS (Pmode,
641                                                                       spreg,
642                                                                       val));
643       RTX_FRAME_RELATED_P (XVECEXP (pat, 0, total_consec + 1)) = 1;
644       d_to_save = ndregs_consec;
645       dregno = REG_R7 + 1 - ndregs_consec;
646       pregno = REG_P5 + 1 - npregs_consec;
647       for (i = 0; i < total_consec; i++)
648         {
649           rtx memref = gen_rtx_MEM (word_mode,
650                                     gen_rtx_PLUS (Pmode, spreg,
651                                                   GEN_INT (- i * 4 - 4)));
652           rtx subpat;
653           if (d_to_save > 0)
654             {
655               subpat = gen_rtx_SET (VOIDmode, memref, gen_rtx_REG (word_mode,
656                                                                    dregno++));
657               d_to_save--;
658             }
659           else
660             {
661               subpat = gen_rtx_SET (VOIDmode, memref, gen_rtx_REG (word_mode,
662                                                                    pregno++));
663             }
664           XVECEXP (pat, 0, i + 1) = subpat;
665           RTX_FRAME_RELATED_P (subpat) = 1;
666         }
667       insn = emit_insn (pat);
668       RTX_FRAME_RELATED_P (insn) = 1;
669     }
670
671   for (dregno = REG_R0; ndregs != ndregs_consec; dregno++)
672     {
673       if (must_save_p (is_inthandler, dregno))
674         {
675           rtx insn = emit_move_insn (predec, gen_rtx_REG (word_mode, dregno));
676           RTX_FRAME_RELATED_P (insn) = 1;
677           ndregs--;
678         }
679     }
680   for (pregno = REG_P0; npregs != npregs_consec; pregno++)
681     {
682       if (must_save_p (is_inthandler, pregno))
683         {
684           rtx insn = emit_move_insn (predec, gen_rtx_REG (word_mode, pregno));
685           RTX_FRAME_RELATED_P (insn) = 1;
686           npregs--;
687         }
688     }
689   for (i = REG_P7 + 1; i < REG_CC; i++)
690     if (saveall 
691         || (is_inthandler
692             && (df_regs_ever_live_p (i)
693                 || (!leaf_function_p () && call_used_regs[i]))))
694       {
695         rtx insn;
696         if (i == REG_A0 || i == REG_A1)
697           insn = emit_move_insn (gen_rtx_MEM (PDImode, predec1),
698                                  gen_rtx_REG (PDImode, i));
699         else
700           insn = emit_move_insn (predec, gen_rtx_REG (SImode, i));
701         RTX_FRAME_RELATED_P (insn) = 1;
702       }
703 }
704
705 /* Emit code to restore registers in the epilogue.  SAVEALL is nonzero if we
706    must save all registers; this is used for interrupt handlers.
707    SPREG contains (reg:SI REG_SP).  IS_INTHANDLER is true if we're doing
708    this for an interrupt (or exception) handler.  */
709
710 static void
711 expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler)
712 {
713   rtx postinc1 = gen_rtx_POST_INC (SImode, spreg);
714   rtx postinc = gen_rtx_MEM (SImode, postinc1);
715
716   int ndregs = saveall ? 8 : n_dregs_to_save (is_inthandler, false);
717   int npregs = saveall ? 6 : n_pregs_to_save (is_inthandler, false);
718   int ndregs_consec = saveall ? 8 : n_dregs_to_save (is_inthandler, true);
719   int npregs_consec = saveall ? 6 : n_pregs_to_save (is_inthandler, true);
720   int total_consec = ndregs_consec + npregs_consec;
721   int i, regno;
722   rtx insn;
723
724   /* A slightly crude technique to stop flow from trying to delete "dead"
725      insns.  */
726   MEM_VOLATILE_P (postinc) = 1;
727
728   for (i = REG_CC - 1; i > REG_P7; i--)
729     if (saveall
730         || (is_inthandler
731             && (df_regs_ever_live_p (i)
732                 || (!leaf_function_p () && call_used_regs[i]))))
733       {
734         if (i == REG_A0 || i == REG_A1)
735           {
736             rtx mem = gen_rtx_MEM (PDImode, postinc1);
737             MEM_VOLATILE_P (mem) = 1;
738             emit_move_insn (gen_rtx_REG (PDImode, i), mem);
739           }
740         else
741           emit_move_insn (gen_rtx_REG (SImode, i), postinc);
742       }
743
744   regno = REG_P5 - npregs_consec;
745   for (; npregs != npregs_consec; regno--)
746     {
747       if (must_save_p (is_inthandler, regno))
748         {
749           emit_move_insn (gen_rtx_REG (word_mode, regno), postinc);
750           npregs--;
751         }
752     }
753   regno = REG_R7 - ndregs_consec;
754   for (; ndregs != ndregs_consec; regno--)
755     {
756       if (must_save_p (is_inthandler, regno))
757         {
758           emit_move_insn (gen_rtx_REG (word_mode, regno), postinc);
759           ndregs--;
760         }
761     }
762
763   if (total_consec != 0)
764     {
765       rtx pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_consec + 1));
766       XVECEXP (pat, 0, 0)
767         = gen_rtx_SET (VOIDmode, spreg,
768                        gen_rtx_PLUS (Pmode, spreg,
769                                      GEN_INT (total_consec * 4)));
770
771       if (npregs_consec > 0)
772         regno = REG_P5 + 1;
773       else
774         regno = REG_R7 + 1;
775
776       for (i = 0; i < total_consec; i++)
777         {
778           rtx addr = (i > 0
779                       ? gen_rtx_PLUS (Pmode, spreg, GEN_INT (i * 4))
780                       : spreg);
781           rtx memref = gen_rtx_MEM (word_mode, addr);
782
783           regno--;
784           XVECEXP (pat, 0, i + 1)
785             = gen_rtx_SET (VOIDmode, gen_rtx_REG (word_mode, regno), memref);
786
787           if (npregs_consec > 0)
788             {
789               if (--npregs_consec == 0)
790                 regno = REG_R7 + 1;
791             }
792         }
793
794       insn = emit_insn (pat);
795       RTX_FRAME_RELATED_P (insn) = 1;
796     }
797   if (saveall || is_inthandler)
798     {
799       for (regno = REG_LB1; regno >= REG_LT0; regno--)
800         if (! current_function_is_leaf
801             || cfun->machine->has_hardware_loops
802             || cfun->machine->has_loopreg_clobber
803             || (ENABLE_WA_05000257 && (regno == REG_LC0 || regno == REG_LC1)))
804           emit_move_insn (gen_rtx_REG (SImode, regno), postinc);
805
806       emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc);
807     }
808 }
809
810 /* Perform any needed actions needed for a function that is receiving a
811    variable number of arguments.
812
813    CUM is as above.
814
815    MODE and TYPE are the mode and type of the current parameter.
816
817    PRETEND_SIZE is a variable that should be set to the amount of stack
818    that must be pushed by the prolog to pretend that our caller pushed
819    it.
820
821    Normally, this macro will push all remaining incoming registers on the
822    stack and set PRETEND_SIZE to the length of the registers pushed.  
823
824    Blackfin specific :
825    - VDSP C compiler manual (our ABI) says that a variable args function
826      should save the R0, R1 and R2 registers in the stack.
827    - The caller will always leave space on the stack for the
828      arguments that are passed in registers, so we dont have
829      to leave any extra space.
830    - now, the vastart pointer can access all arguments from the stack.  */
831
832 static void
833 setup_incoming_varargs (CUMULATIVE_ARGS *cum,
834                         enum machine_mode mode ATTRIBUTE_UNUSED,
835                         tree type ATTRIBUTE_UNUSED, int *pretend_size,
836                         int no_rtl)
837 {
838   rtx mem;
839   int i;
840
841   if (no_rtl)
842     return;
843
844   /* The move for named arguments will be generated automatically by the
845      compiler.  We need to generate the move rtx for the unnamed arguments
846      if they are in the first 3 words.  We assume at least 1 named argument
847      exists, so we never generate [ARGP] = R0 here.  */
848
849   for (i = cum->words + 1; i < max_arg_registers; i++)
850     {
851       mem = gen_rtx_MEM (Pmode,
852                          plus_constant (arg_pointer_rtx, (i * UNITS_PER_WORD)));
853       emit_move_insn (mem, gen_rtx_REG (Pmode, i));
854     }
855
856   *pretend_size = 0;
857 }
858
859 /* Value should be nonzero if functions must have frame pointers.
860    Zero means the frame pointer need not be set up (and parms may
861    be accessed via the stack pointer) in functions that seem suitable.  */
862
863 static bool
864 bfin_frame_pointer_required (void) 
865 {
866   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
867
868   if (fkind != SUBROUTINE)
869     return true;
870
871   /* We turn on -fomit-frame-pointer if -momit-leaf-frame-pointer is used,
872      so we have to override it for non-leaf functions.  */
873   if (TARGET_OMIT_LEAF_FRAME_POINTER && ! current_function_is_leaf)
874     return true;
875
876   return false;
877 }
878
879 /* Return the number of registers pushed during the prologue.  */
880
881 static int
882 n_regs_saved_by_prologue (void)
883 {
884   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
885   bool is_inthandler = fkind != SUBROUTINE;
886   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
887   bool all = (lookup_attribute ("saveall", attrs) != NULL_TREE
888               || (is_inthandler && !current_function_is_leaf));
889   int ndregs = all ? 8 : n_dregs_to_save (is_inthandler, false);
890   int npregs = all ? 6 : n_pregs_to_save (is_inthandler, false);
891   int n = ndregs + npregs;
892   int i;
893
894   if (all || stack_frame_needed_p ())
895     n += 2;
896   else
897     {
898       if (must_save_fp_p ())
899         n++;
900       if (must_save_rets_p ())
901         n++;
902     }
903
904   if (fkind != SUBROUTINE || all)
905     {
906       /* Increment once for ASTAT.  */
907       n++;
908       if (! current_function_is_leaf
909           || cfun->machine->has_hardware_loops
910           || cfun->machine->has_loopreg_clobber)
911         {
912           n += 6;
913         }
914     }
915
916   if (fkind != SUBROUTINE)
917     {
918       /* RETE/X/N.  */
919       if (lookup_attribute ("nesting", attrs))
920         n++;
921     }
922
923   for (i = REG_P7 + 1; i < REG_CC; i++)
924     if (all
925         || (fkind != SUBROUTINE
926             && (df_regs_ever_live_p (i)
927                 || (!leaf_function_p () && call_used_regs[i]))))
928       n += i == REG_A0 || i == REG_A1 ? 2 : 1;
929
930   return n;
931 }
932
933 /* Given FROM and TO register numbers, say whether this elimination is
934    allowed.  Frame pointer elimination is automatically handled.
935
936    All other eliminations are valid.  */
937
938 static bool
939 bfin_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
940 {
941   return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true);
942 }
943
944 /* Return the offset between two registers, one to be eliminated, and the other
945    its replacement, at the start of a routine.  */
946
947 HOST_WIDE_INT
948 bfin_initial_elimination_offset (int from, int to)
949 {
950   HOST_WIDE_INT offset = 0;
951
952   if (from == ARG_POINTER_REGNUM)
953     offset = n_regs_saved_by_prologue () * 4;
954
955   if (to == STACK_POINTER_REGNUM)
956     {
957       if (crtl->outgoing_args_size >= FIXED_STACK_AREA)
958         offset += crtl->outgoing_args_size;
959       else if (crtl->outgoing_args_size)
960         offset += FIXED_STACK_AREA;
961
962       offset += get_frame_size ();
963     }
964
965   return offset;
966 }
967
968 /* Emit code to load a constant CONSTANT into register REG; setting
969    RTX_FRAME_RELATED_P on all insns we generate if RELATED is true.
970    Make sure that the insns we generate need not be split.  */
971
972 static void
973 frame_related_constant_load (rtx reg, HOST_WIDE_INT constant, bool related)
974 {
975   rtx insn;
976   rtx cst = GEN_INT (constant);
977
978   if (constant >= -32768 && constant < 65536)
979     insn = emit_move_insn (reg, cst);
980   else
981     {
982       /* We don't call split_load_immediate here, since dwarf2out.c can get
983          confused about some of the more clever sequences it can generate.  */
984       insn = emit_insn (gen_movsi_high (reg, cst));
985       if (related)
986         RTX_FRAME_RELATED_P (insn) = 1;
987       insn = emit_insn (gen_movsi_low (reg, reg, cst));
988     }
989   if (related)
990     RTX_FRAME_RELATED_P (insn) = 1;
991 }
992
993 /* Generate efficient code to add a value to a P register.
994    Set RTX_FRAME_RELATED_P on the generated insns if FRAME is nonzero.
995    EPILOGUE_P is zero if this function is called for prologue,
996    otherwise it's nonzero. And it's less than zero if this is for
997    sibcall epilogue.  */
998
999 static void
1000 add_to_reg (rtx reg, HOST_WIDE_INT value, int frame, int epilogue_p)
1001 {
1002   if (value == 0)
1003     return;
1004
1005   /* Choose whether to use a sequence using a temporary register, or
1006      a sequence with multiple adds.  We can add a signed 7-bit value
1007      in one instruction.  */
1008   if (value > 120 || value < -120)
1009     {
1010       rtx tmpreg;
1011       rtx tmpreg2;
1012       rtx insn;
1013
1014       tmpreg2 = NULL_RTX;
1015
1016       /* For prologue or normal epilogue, P1 can be safely used
1017          as the temporary register. For sibcall epilogue, we try to find
1018          a call used P register, which will be restored in epilogue.
1019          If we cannot find such a P register, we have to use one I register
1020          to help us.  */
1021
1022       if (epilogue_p >= 0)
1023         tmpreg = gen_rtx_REG (SImode, REG_P1);
1024       else
1025         {
1026           int i;
1027           for (i = REG_P0; i <= REG_P5; i++)
1028             if ((df_regs_ever_live_p (i) && ! call_used_regs[i])
1029                 || (!TARGET_FDPIC
1030                     && i == PIC_OFFSET_TABLE_REGNUM
1031                     && (crtl->uses_pic_offset_table
1032                         || (TARGET_ID_SHARED_LIBRARY
1033                             && ! current_function_is_leaf))))
1034               break;
1035           if (i <= REG_P5)
1036             tmpreg = gen_rtx_REG (SImode, i);
1037           else
1038             {
1039               tmpreg = gen_rtx_REG (SImode, REG_P1);
1040               tmpreg2 = gen_rtx_REG (SImode, REG_I0);
1041               emit_move_insn (tmpreg2, tmpreg);
1042             }
1043         }
1044
1045       if (frame)
1046         frame_related_constant_load (tmpreg, value, TRUE);
1047       else
1048         insn = emit_move_insn (tmpreg, GEN_INT (value));
1049
1050       insn = emit_insn (gen_addsi3 (reg, reg, tmpreg));
1051       if (frame)
1052         RTX_FRAME_RELATED_P (insn) = 1;
1053
1054       if (tmpreg2 != NULL_RTX)
1055         emit_move_insn (tmpreg, tmpreg2);
1056     }
1057   else
1058     do
1059       {
1060         int size = value;
1061         rtx insn;
1062
1063         if (size > 60)
1064           size = 60;
1065         else if (size < -60)
1066           /* We could use -62, but that would leave the stack unaligned, so
1067              it's no good.  */
1068           size = -60;
1069
1070         insn = emit_insn (gen_addsi3 (reg, reg, GEN_INT (size)));
1071         if (frame)
1072           RTX_FRAME_RELATED_P (insn) = 1;
1073         value -= size;
1074       }
1075     while (value != 0);
1076 }
1077
1078 /* Generate a LINK insn for a frame sized FRAME_SIZE.  If this constant
1079    is too large, generate a sequence of insns that has the same effect.
1080    SPREG contains (reg:SI REG_SP).  */
1081
1082 static void
1083 emit_link_insn (rtx spreg, HOST_WIDE_INT frame_size)
1084 {
1085   HOST_WIDE_INT link_size = frame_size;
1086   rtx insn;
1087   int i;
1088
1089   if (link_size > 262140)
1090     link_size = 262140;
1091
1092   /* Use a LINK insn with as big a constant as possible, then subtract
1093      any remaining size from the SP.  */
1094   insn = emit_insn (gen_link (GEN_INT (-8 - link_size)));
1095   RTX_FRAME_RELATED_P (insn) = 1;
1096
1097   for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1098     {
1099       rtx set = XVECEXP (PATTERN (insn), 0, i);
1100       gcc_assert (GET_CODE (set) == SET);
1101       RTX_FRAME_RELATED_P (set) = 1;
1102     }
1103
1104   frame_size -= link_size;
1105
1106   if (frame_size > 0)
1107     {
1108       /* Must use a call-clobbered PREG that isn't the static chain.  */
1109       rtx tmpreg = gen_rtx_REG (Pmode, REG_P1);
1110
1111       frame_related_constant_load (tmpreg, -frame_size, TRUE);
1112       insn = emit_insn (gen_addsi3 (spreg, spreg, tmpreg));
1113       RTX_FRAME_RELATED_P (insn) = 1;
1114     }
1115 }
1116
1117 /* Return the number of bytes we must reserve for outgoing arguments
1118    in the current function's stack frame.  */
1119
1120 static HOST_WIDE_INT
1121 arg_area_size (void)
1122 {
1123   if (crtl->outgoing_args_size)
1124     {
1125       if (crtl->outgoing_args_size >= FIXED_STACK_AREA)
1126         return crtl->outgoing_args_size;
1127       else
1128         return FIXED_STACK_AREA;
1129     }
1130   return 0;
1131 }
1132
1133 /* Save RETS and FP, and allocate a stack frame.  ALL is true if the
1134    function must save all its registers (true only for certain interrupt
1135    handlers).  */
1136
1137 static void
1138 do_link (rtx spreg, HOST_WIDE_INT frame_size, bool all)
1139 {
1140   frame_size += arg_area_size ();
1141
1142   if (all
1143       || stack_frame_needed_p ()
1144       || (must_save_rets_p () && must_save_fp_p ()))
1145     emit_link_insn (spreg, frame_size);
1146   else
1147     {
1148       if (must_save_rets_p ())
1149         {
1150           rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
1151                                             gen_rtx_PRE_DEC (Pmode, spreg)),
1152                                bfin_rets_rtx);
1153           rtx insn = emit_insn (pat);
1154           RTX_FRAME_RELATED_P (insn) = 1;
1155         }
1156       if (must_save_fp_p ())
1157         {
1158           rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
1159                                             gen_rtx_PRE_DEC (Pmode, spreg)),
1160                                gen_rtx_REG (Pmode, REG_FP));
1161           rtx insn = emit_insn (pat);
1162           RTX_FRAME_RELATED_P (insn) = 1;
1163         }
1164       add_to_reg (spreg, -frame_size, 1, 0);
1165     }
1166 }
1167
1168 /* Like do_link, but used for epilogues to deallocate the stack frame.
1169    EPILOGUE_P is zero if this function is called for prologue,
1170    otherwise it's nonzero. And it's less than zero if this is for
1171    sibcall epilogue.  */
1172
1173 static void
1174 do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all, int epilogue_p)
1175 {
1176   frame_size += arg_area_size ();
1177
1178   if (stack_frame_needed_p ())
1179     emit_insn (gen_unlink ());
1180   else 
1181     {
1182       rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg));
1183
1184       add_to_reg (spreg, frame_size, 0, epilogue_p);
1185       if (all || must_save_fp_p ())
1186         {
1187           rtx fpreg = gen_rtx_REG (Pmode, REG_FP);
1188           emit_move_insn (fpreg, postinc);
1189           emit_use (fpreg);
1190         }
1191       if (all || must_save_rets_p ())
1192         {
1193           emit_move_insn (bfin_rets_rtx, postinc);
1194           emit_use (bfin_rets_rtx);
1195         }
1196     }
1197 }
1198
1199 /* Generate a prologue suitable for a function of kind FKIND.  This is
1200    called for interrupt and exception handler prologues.
1201    SPREG contains (reg:SI REG_SP).  */
1202
1203 static void
1204 expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind, bool all)
1205 {
1206   HOST_WIDE_INT frame_size = get_frame_size ();
1207   rtx predec1 = gen_rtx_PRE_DEC (SImode, spreg);
1208   rtx predec = gen_rtx_MEM (SImode, predec1);
1209   rtx insn;
1210   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1211   tree kspisusp = lookup_attribute ("kspisusp", attrs);
1212
1213   if (kspisusp)
1214     {
1215       insn = emit_move_insn (spreg, gen_rtx_REG (Pmode, REG_USP));
1216       RTX_FRAME_RELATED_P (insn) = 1;
1217     }
1218
1219   /* We need space on the stack in case we need to save the argument
1220      registers.  */
1221   if (fkind == EXCPT_HANDLER)
1222     {
1223       insn = emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (-12)));
1224       RTX_FRAME_RELATED_P (insn) = 1;
1225     }
1226
1227   /* If we're calling other functions, they won't save their call-clobbered
1228      registers, so we must save everything here.  */
1229   if (!current_function_is_leaf)
1230     all = true;
1231   expand_prologue_reg_save (spreg, all, true);
1232
1233   if (ENABLE_WA_05000283 || ENABLE_WA_05000315)
1234     {
1235       rtx chipid = GEN_INT (trunc_int_for_mode (0xFFC00014, SImode));
1236       rtx p5reg = gen_rtx_REG (Pmode, REG_P5);
1237       emit_insn (gen_movbi (bfin_cc_rtx, const1_rtx));
1238       emit_insn (gen_movsi_high (p5reg, chipid));
1239       emit_insn (gen_movsi_low (p5reg, p5reg, chipid));
1240       emit_insn (gen_dummy_load (p5reg, bfin_cc_rtx));
1241     }
1242   
1243   if (lookup_attribute ("nesting", attrs))
1244     {
1245       rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
1246       insn = emit_move_insn (predec, srcreg);
1247       RTX_FRAME_RELATED_P (insn) = 1;
1248     }
1249
1250   do_link (spreg, frame_size, all);
1251
1252   if (fkind == EXCPT_HANDLER)
1253     {
1254       rtx r0reg = gen_rtx_REG (SImode, REG_R0);
1255       rtx r1reg = gen_rtx_REG (SImode, REG_R1);
1256       rtx r2reg = gen_rtx_REG (SImode, REG_R2);
1257       rtx insn;
1258
1259       insn = emit_move_insn (r0reg, gen_rtx_REG (SImode, REG_SEQSTAT));
1260       insn = emit_insn (gen_ashrsi3 (r0reg, r0reg, GEN_INT (26)));
1261       insn = emit_insn (gen_ashlsi3 (r0reg, r0reg, GEN_INT (26)));
1262       insn = emit_move_insn (r1reg, spreg);
1263       insn = emit_move_insn (r2reg, gen_rtx_REG (Pmode, REG_FP));
1264       insn = emit_insn (gen_addsi3 (r2reg, r2reg, GEN_INT (8)));
1265     }
1266 }
1267
1268 /* Generate an epilogue suitable for a function of kind FKIND.  This is
1269    called for interrupt and exception handler epilogues.
1270    SPREG contains (reg:SI REG_SP).  */
1271
1272 static void
1273 expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all)
1274 {
1275   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1276   rtx postinc1 = gen_rtx_POST_INC (SImode, spreg);
1277   rtx postinc = gen_rtx_MEM (SImode, postinc1);
1278
1279   /* A slightly crude technique to stop flow from trying to delete "dead"
1280      insns.  */
1281   MEM_VOLATILE_P (postinc) = 1;
1282
1283   do_unlink (spreg, get_frame_size (), all, 1);
1284
1285   if (lookup_attribute ("nesting", attrs))
1286     {
1287       rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
1288       emit_move_insn (srcreg, postinc);
1289     }
1290
1291   /* If we're calling other functions, they won't save their call-clobbered
1292      registers, so we must save (and restore) everything here.  */
1293   if (!current_function_is_leaf)
1294     all = true;
1295
1296   expand_epilogue_reg_restore (spreg, all, true);
1297
1298   /* Deallocate any space we left on the stack in case we needed to save the
1299      argument registers.  */
1300   if (fkind == EXCPT_HANDLER)
1301     emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (12)));
1302
1303   emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, ret_regs[fkind])));
1304 }
1305
1306 /* Used while emitting the prologue to generate code to load the correct value
1307    into the PIC register, which is passed in DEST.  */
1308
1309 static rtx
1310 bfin_load_pic_reg (rtx dest)
1311 {
1312   struct cgraph_local_info *i = NULL;
1313   rtx addr, insn;
1314  
1315   i = cgraph_local_info (current_function_decl);
1316  
1317   /* Functions local to the translation unit don't need to reload the
1318      pic reg, since the caller always passes a usable one.  */
1319   if (i && i->local)
1320     return pic_offset_table_rtx;
1321       
1322   if (bfin_lib_id_given)
1323     addr = plus_constant (pic_offset_table_rtx, -4 - bfin_library_id * 4);
1324   else
1325     addr = gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
1326                          gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
1327                                          UNSPEC_LIBRARY_OFFSET));
1328   insn = emit_insn (gen_movsi (dest, gen_rtx_MEM (Pmode, addr)));
1329   return dest;
1330 }
1331
1332 /* Generate RTL for the prologue of the current function.  */
1333
1334 void
1335 bfin_expand_prologue (void)
1336 {
1337   HOST_WIDE_INT frame_size = get_frame_size ();
1338   rtx spreg = gen_rtx_REG (Pmode, REG_SP);
1339   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
1340   rtx pic_reg_loaded = NULL_RTX;
1341   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1342   bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
1343
1344   if (fkind != SUBROUTINE)
1345     {
1346       expand_interrupt_handler_prologue (spreg, fkind, all);
1347       return;
1348     }
1349
1350   if (crtl->limit_stack
1351       || (TARGET_STACK_CHECK_L1
1352           && !DECL_NO_LIMIT_STACK (current_function_decl)))
1353     {
1354       HOST_WIDE_INT offset
1355         = bfin_initial_elimination_offset (ARG_POINTER_REGNUM,
1356                                            STACK_POINTER_REGNUM);
1357       rtx lim = crtl->limit_stack ? stack_limit_rtx : NULL_RTX;
1358       rtx p2reg = gen_rtx_REG (Pmode, REG_P2);
1359
1360       if (!lim)
1361         {
1362           emit_move_insn (p2reg, gen_int_mode (0xFFB00000, SImode));
1363           emit_move_insn (p2reg, gen_rtx_MEM (Pmode, p2reg));
1364           lim = p2reg;
1365         }
1366       if (GET_CODE (lim) == SYMBOL_REF)
1367         {
1368           if (TARGET_ID_SHARED_LIBRARY)
1369             {
1370               rtx p1reg = gen_rtx_REG (Pmode, REG_P1);
1371               rtx val;
1372               pic_reg_loaded = bfin_load_pic_reg (p2reg);
1373               val = legitimize_pic_address (stack_limit_rtx, p1reg,
1374                                             pic_reg_loaded);
1375               emit_move_insn (p1reg, val);
1376               frame_related_constant_load (p2reg, offset, FALSE);
1377               emit_insn (gen_addsi3 (p2reg, p2reg, p1reg));
1378               lim = p2reg;
1379             }
1380           else
1381             {
1382               rtx limit = plus_constant (lim, offset);
1383               emit_move_insn (p2reg, limit);
1384               lim = p2reg;
1385             }
1386         }
1387       else
1388         {
1389           if (lim != p2reg)
1390             emit_move_insn (p2reg, lim);
1391           add_to_reg (p2reg, offset, 0, 0);
1392           lim = p2reg;
1393         }
1394       emit_insn (gen_compare_lt (bfin_cc_rtx, spreg, lim));
1395       emit_insn (gen_trapifcc ());
1396     }
1397   expand_prologue_reg_save (spreg, all, false);
1398
1399   do_link (spreg, frame_size, all);
1400
1401   if (TARGET_ID_SHARED_LIBRARY
1402       && !TARGET_SEP_DATA
1403       && (crtl->uses_pic_offset_table
1404           || !current_function_is_leaf))
1405     bfin_load_pic_reg (pic_offset_table_rtx);
1406 }
1407
1408 /* Generate RTL for the epilogue of the current function.  NEED_RETURN is zero
1409    if this is for a sibcall.  EH_RETURN is nonzero if we're expanding an
1410    eh_return pattern. SIBCALL_P is true if this is a sibcall epilogue,
1411    false otherwise.  */
1412
1413 void
1414 bfin_expand_epilogue (int need_return, int eh_return, bool sibcall_p)
1415 {
1416   rtx spreg = gen_rtx_REG (Pmode, REG_SP);
1417   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
1418   int e = sibcall_p ? -1 : 1;
1419   tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1420   bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
1421
1422   if (fkind != SUBROUTINE)
1423     {
1424       expand_interrupt_handler_epilogue (spreg, fkind, all);
1425       return;
1426     }
1427
1428   do_unlink (spreg, get_frame_size (), all, e);
1429
1430   expand_epilogue_reg_restore (spreg, all, false);
1431
1432   /* Omit the return insn if this is for a sibcall.  */
1433   if (! need_return)
1434     return;
1435
1436   if (eh_return)
1437     emit_insn (gen_addsi3 (spreg, spreg, gen_rtx_REG (Pmode, REG_P2)));
1438
1439   emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, REG_RETS)));
1440 }
1441 \f
1442 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
1443
1444 int
1445 bfin_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
1446                            unsigned int new_reg)
1447 {
1448   /* Interrupt functions can only use registers that have already been
1449      saved by the prologue, even if they would normally be
1450      call-clobbered.  */
1451
1452   if (funkind (TREE_TYPE (current_function_decl)) != SUBROUTINE
1453       && !df_regs_ever_live_p (new_reg))
1454     return 0;
1455
1456   return 1;
1457 }
1458
1459 /* Return the value of the return address for the frame COUNT steps up
1460    from the current frame, after the prologue.
1461    We punt for everything but the current frame by returning const0_rtx.  */
1462
1463 rtx
1464 bfin_return_addr_rtx (int count)
1465 {
1466   if (count != 0)
1467     return const0_rtx;
1468
1469   return get_hard_reg_initial_val (Pmode, REG_RETS);
1470 }
1471
1472 static rtx
1473 bfin_delegitimize_address (rtx orig_x)
1474 {
1475   rtx x = orig_x;
1476
1477   if (GET_CODE (x) != MEM)
1478     return orig_x;
1479
1480   x = XEXP (x, 0);
1481   if (GET_CODE (x) == PLUS
1482       && GET_CODE (XEXP (x, 1)) == UNSPEC
1483       && XINT (XEXP (x, 1), 1) == UNSPEC_MOVE_PIC
1484       && GET_CODE (XEXP (x, 0)) == REG
1485       && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
1486     return XVECEXP (XEXP (x, 1), 0, 0);
1487
1488   return orig_x;
1489 }
1490
1491 /* This predicate is used to compute the length of a load/store insn.
1492    OP is a MEM rtx, we return nonzero if its addressing mode requires a
1493    32-bit instruction.  */
1494
1495 int
1496 effective_address_32bit_p (rtx op, enum machine_mode mode) 
1497 {
1498   HOST_WIDE_INT offset;
1499
1500   mode = GET_MODE (op);
1501   op = XEXP (op, 0);
1502
1503   if (GET_CODE (op) != PLUS)
1504     {
1505       gcc_assert (REG_P (op) || GET_CODE (op) == POST_INC
1506                   || GET_CODE (op) == PRE_DEC || GET_CODE (op) == POST_DEC);
1507       return 0;
1508     }
1509
1510   if (GET_CODE (XEXP (op, 1)) == UNSPEC)
1511     return 1;
1512
1513   offset = INTVAL (XEXP (op, 1));
1514
1515   /* All byte loads use a 16-bit offset.  */
1516   if (GET_MODE_SIZE (mode) == 1)
1517     return 1;
1518
1519   if (GET_MODE_SIZE (mode) == 4)
1520     {
1521       /* Frame pointer relative loads can use a negative offset, all others
1522          are restricted to a small positive one.  */
1523       if (XEXP (op, 0) == frame_pointer_rtx)
1524         return offset < -128 || offset > 60;
1525       return offset < 0 || offset > 60;
1526     }
1527
1528   /* Must be HImode now.  */
1529   return offset < 0 || offset > 30;
1530 }
1531
1532 /* Returns true if X is a memory reference using an I register.  */
1533 bool
1534 bfin_dsp_memref_p (rtx x)
1535 {
1536   if (! MEM_P (x))
1537     return false;
1538   x = XEXP (x, 0);
1539   if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_INC
1540       || GET_CODE (x) == POST_DEC || GET_CODE (x) == PRE_DEC)
1541     x = XEXP (x, 0);
1542   return IREG_P (x);
1543 }
1544
1545 /* Return cost of the memory address ADDR.
1546    All addressing modes are equally cheap on the Blackfin.  */
1547
1548 static int
1549 bfin_address_cost (rtx addr ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED)
1550 {
1551   return 1;
1552 }
1553
1554 /* Subroutine of print_operand; used to print a memory reference X to FILE.  */
1555
1556 void
1557 print_address_operand (FILE *file, rtx x)
1558 {
1559   switch (GET_CODE (x))
1560     {
1561     case PLUS:
1562       output_address (XEXP (x, 0));
1563       fprintf (file, "+");
1564       output_address (XEXP (x, 1));
1565       break;
1566
1567     case PRE_DEC:
1568       fprintf (file, "--");
1569       output_address (XEXP (x, 0));    
1570       break;
1571     case POST_INC:
1572       output_address (XEXP (x, 0));
1573       fprintf (file, "++");
1574       break;
1575     case POST_DEC:
1576       output_address (XEXP (x, 0));
1577       fprintf (file, "--");
1578       break;
1579
1580     default:
1581       gcc_assert (GET_CODE (x) != MEM);
1582       print_operand (file, x, 0);
1583       break;
1584     }
1585 }
1586
1587 /* Adding intp DImode support by Tony
1588  * -- Q: (low  word)
1589  * -- R: (high word)
1590  */
1591
1592 void
1593 print_operand (FILE *file, rtx x, char code)
1594 {
1595   enum machine_mode mode;
1596
1597   if (code == '!')
1598     {
1599       if (GET_MODE (current_output_insn) == SImode)
1600         fprintf (file, " ||");
1601       else
1602         fprintf (file, ";");
1603       return;
1604     }
1605
1606   mode = GET_MODE (x);
1607
1608   switch (code)
1609     {
1610     case 'j':
1611       switch (GET_CODE (x))
1612         {
1613         case EQ:
1614           fprintf (file, "e");
1615           break;
1616         case NE:
1617           fprintf (file, "ne");
1618           break;
1619         case GT:
1620           fprintf (file, "g");
1621           break;
1622         case LT:
1623           fprintf (file, "l");
1624           break;
1625         case GE:
1626           fprintf (file, "ge");
1627           break;
1628         case LE:
1629           fprintf (file, "le");
1630           break;
1631         case GTU:
1632           fprintf (file, "g");
1633           break;
1634         case LTU:
1635           fprintf (file, "l");
1636           break;
1637         case GEU:
1638           fprintf (file, "ge");
1639           break;
1640         case LEU:
1641           fprintf (file, "le");
1642           break;
1643         default:
1644           output_operand_lossage ("invalid %%j value");
1645         }
1646       break;
1647     
1648     case 'J':                                    /* reverse logic */
1649       switch (GET_CODE(x))
1650         {
1651         case EQ:
1652           fprintf (file, "ne");
1653           break;
1654         case NE:
1655           fprintf (file, "e");
1656           break;
1657         case GT:
1658           fprintf (file, "le");
1659           break;
1660         case LT:
1661           fprintf (file, "ge");
1662           break;
1663         case GE:
1664           fprintf (file, "l");
1665           break;
1666         case LE:
1667           fprintf (file, "g");
1668           break;
1669         case GTU:
1670           fprintf (file, "le");
1671           break;
1672         case LTU:
1673           fprintf (file, "ge");
1674           break;
1675         case GEU:
1676           fprintf (file, "l");
1677           break;
1678         case LEU:
1679           fprintf (file, "g");
1680           break;
1681         default:
1682           output_operand_lossage ("invalid %%J value");
1683         }
1684       break;
1685
1686     default:
1687       switch (GET_CODE (x))
1688         {
1689         case REG:
1690           if (code == 'h')
1691             {
1692               if (REGNO (x) < 32)
1693                 fprintf (file, "%s", short_reg_names[REGNO (x)]);
1694               else
1695                 output_operand_lossage ("invalid operand for code '%c'", code);
1696             }
1697           else if (code == 'd')
1698             {
1699               if (REGNO (x) < 32)
1700                 fprintf (file, "%s", high_reg_names[REGNO (x)]);
1701               else
1702                 output_operand_lossage ("invalid operand for code '%c'", code);
1703             }
1704           else if (code == 'w')
1705             {
1706               if (REGNO (x) == REG_A0 || REGNO (x) == REG_A1)
1707                 fprintf (file, "%s.w", reg_names[REGNO (x)]);
1708               else
1709                 output_operand_lossage ("invalid operand for code '%c'", code);
1710             }
1711           else if (code == 'x')
1712             {
1713               if (REGNO (x) == REG_A0 || REGNO (x) == REG_A1)
1714                 fprintf (file, "%s.x", reg_names[REGNO (x)]);
1715               else
1716                 output_operand_lossage ("invalid operand for code '%c'", code);
1717             }
1718           else if (code == 'v')
1719             {
1720               if (REGNO (x) == REG_A0)
1721                 fprintf (file, "AV0");
1722               else if (REGNO (x) == REG_A1)
1723                 fprintf (file, "AV1");
1724               else
1725                 output_operand_lossage ("invalid operand for code '%c'", code);
1726             }
1727           else if (code == 'D')
1728             {
1729               if (D_REGNO_P (REGNO (x)))
1730                 fprintf (file, "%s", dregs_pair_names[REGNO (x)]);
1731               else
1732                 output_operand_lossage ("invalid operand for code '%c'", code);
1733             }
1734           else if (code == 'H')
1735             {
1736               if ((mode == DImode || mode == DFmode) && REG_P (x))
1737                 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
1738               else
1739                 output_operand_lossage ("invalid operand for code '%c'", code);
1740             }
1741           else if (code == 'T')
1742             {
1743               if (D_REGNO_P (REGNO (x)))
1744                 fprintf (file, "%s", byte_reg_names[REGNO (x)]);
1745               else
1746                 output_operand_lossage ("invalid operand for code '%c'", code);
1747             }
1748           else 
1749             fprintf (file, "%s", reg_names[REGNO (x)]);
1750           break;
1751
1752         case MEM:
1753           fputc ('[', file);
1754           x = XEXP (x,0);
1755           print_address_operand (file, x);
1756           fputc (']', file);
1757           break;
1758
1759         case CONST_INT:
1760           if (code == 'M')
1761             {
1762               switch (INTVAL (x))
1763                 {
1764                 case MACFLAG_NONE:
1765                   break;
1766                 case MACFLAG_FU:
1767                   fputs ("(FU)", file);
1768                   break;
1769                 case MACFLAG_T:
1770                   fputs ("(T)", file);
1771                   break;
1772                 case MACFLAG_TFU:
1773                   fputs ("(TFU)", file);
1774                   break;
1775                 case MACFLAG_W32:
1776                   fputs ("(W32)", file);
1777                   break;
1778                 case MACFLAG_IS:
1779                   fputs ("(IS)", file);
1780                   break;
1781                 case MACFLAG_IU:
1782                   fputs ("(IU)", file);
1783                   break;
1784                 case MACFLAG_IH:
1785                   fputs ("(IH)", file);
1786                   break;
1787                 case MACFLAG_M:
1788                   fputs ("(M)", file);
1789                   break;
1790                 case MACFLAG_IS_M:
1791                   fputs ("(IS,M)", file);
1792                   break;
1793                 case MACFLAG_ISS2:
1794                   fputs ("(ISS2)", file);
1795                   break;
1796                 case MACFLAG_S2RND:
1797                   fputs ("(S2RND)", file);
1798                   break;
1799                 default:
1800                   gcc_unreachable ();
1801                 }
1802               break;
1803             }
1804           else if (code == 'b')
1805             {
1806               if (INTVAL (x) == 0)
1807                 fputs ("+=", file);
1808               else if (INTVAL (x) == 1)
1809                 fputs ("-=", file);
1810               else
1811                 gcc_unreachable ();
1812               break;
1813             }
1814           /* Moves to half registers with d or h modifiers always use unsigned
1815              constants.  */
1816           else if (code == 'd')
1817             x = GEN_INT ((INTVAL (x) >> 16) & 0xffff);
1818           else if (code == 'h')
1819             x = GEN_INT (INTVAL (x) & 0xffff);
1820           else if (code == 'N')
1821             x = GEN_INT (-INTVAL (x));
1822           else if (code == 'X')
1823             x = GEN_INT (exact_log2 (0xffffffff & INTVAL (x)));
1824           else if (code == 'Y')
1825             x = GEN_INT (exact_log2 (0xffffffff & ~INTVAL (x)));
1826           else if (code == 'Z')
1827             /* Used for LINK insns.  */
1828             x = GEN_INT (-8 - INTVAL (x));
1829
1830           /* fall through */
1831
1832         case SYMBOL_REF:
1833           output_addr_const (file, x);
1834           break;
1835
1836         case CONST_DOUBLE:
1837           output_operand_lossage ("invalid const_double operand");
1838           break;
1839
1840         case UNSPEC:
1841           switch (XINT (x, 1))
1842             {
1843             case UNSPEC_MOVE_PIC:
1844               output_addr_const (file, XVECEXP (x, 0, 0));
1845               fprintf (file, "@GOT");
1846               break;
1847
1848             case UNSPEC_MOVE_FDPIC:
1849               output_addr_const (file, XVECEXP (x, 0, 0));
1850               fprintf (file, "@GOT17M4");
1851               break;
1852
1853             case UNSPEC_FUNCDESC_GOT17M4:
1854               output_addr_const (file, XVECEXP (x, 0, 0));
1855               fprintf (file, "@FUNCDESC_GOT17M4");
1856               break;
1857
1858             case UNSPEC_LIBRARY_OFFSET:
1859               fprintf (file, "_current_shared_library_p5_offset_");
1860               break;
1861
1862             default:
1863               gcc_unreachable ();
1864             }
1865           break;
1866
1867         default:
1868           output_addr_const (file, x);
1869         }
1870     }
1871 }
1872 \f
1873 /* Argument support functions.  */
1874
1875 /* Initialize a variable CUM of type CUMULATIVE_ARGS
1876    for a call to a function whose data type is FNTYPE.
1877    For a library call, FNTYPE is 0.  
1878    VDSP C Compiler manual, our ABI says that
1879    first 3 words of arguments will use R0, R1 and R2.
1880 */
1881
1882 void
1883 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1884                       rtx libname ATTRIBUTE_UNUSED)
1885 {
1886   static CUMULATIVE_ARGS zero_cum;
1887
1888   *cum = zero_cum;
1889
1890   /* Set up the number of registers to use for passing arguments.  */
1891
1892   cum->nregs = max_arg_registers;
1893   cum->arg_regs = arg_regs;
1894
1895   cum->call_cookie = CALL_NORMAL;
1896   /* Check for a longcall attribute.  */
1897   if (fntype && lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
1898     cum->call_cookie |= CALL_SHORT;
1899   else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
1900     cum->call_cookie |= CALL_LONG;
1901
1902   return;
1903 }
1904
1905 /* Update the data in CUM to advance over an argument
1906    of mode MODE and data type TYPE.
1907    (TYPE is null for libcalls where that information may not be available.)  */
1908
1909 void
1910 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1911                       int named ATTRIBUTE_UNUSED)
1912 {
1913   int count, bytes, words;
1914
1915   bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1916   words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1917
1918   cum->words += words;
1919   cum->nregs -= words;
1920
1921   if (cum->nregs <= 0)
1922     {
1923       cum->nregs = 0;
1924       cum->arg_regs = NULL;
1925     }
1926   else
1927     {
1928       for (count = 1; count <= words; count++)
1929         cum->arg_regs++;
1930     }
1931
1932   return;
1933 }
1934
1935 /* Define where to put the arguments to a function.
1936    Value is zero to push the argument on the stack,
1937    or a hard register in which to store the argument.
1938
1939    MODE is the argument's machine mode.
1940    TYPE is the data type of the argument (as a tree).
1941     This is null for libcalls where that information may
1942     not be available.
1943    CUM is a variable of type CUMULATIVE_ARGS which gives info about
1944     the preceding args and about the function being called.
1945    NAMED is nonzero if this argument is a named parameter
1946     (otherwise it is an extra parameter matching an ellipsis).  */
1947
1948 struct rtx_def *
1949 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1950               int named ATTRIBUTE_UNUSED)
1951 {
1952   int bytes
1953     = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1954
1955   if (mode == VOIDmode)
1956     /* Compute operand 2 of the call insn.  */
1957     return GEN_INT (cum->call_cookie);
1958
1959   if (bytes == -1)
1960     return NULL_RTX;
1961
1962   if (cum->nregs)
1963     return gen_rtx_REG (mode, *(cum->arg_regs));
1964
1965   return NULL_RTX;
1966 }
1967
1968 /* For an arg passed partly in registers and partly in memory,
1969    this is the number of bytes passed in registers.
1970    For args passed entirely in registers or entirely in memory, zero.
1971
1972    Refer VDSP C Compiler manual, our ABI.
1973    First 3 words are in registers. So, if an argument is larger
1974    than the registers available, it will span the register and
1975    stack.   */
1976
1977 static int
1978 bfin_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1979                         tree type ATTRIBUTE_UNUSED,
1980                         bool named ATTRIBUTE_UNUSED)
1981 {
1982   int bytes
1983     = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1984   int bytes_left = cum->nregs * UNITS_PER_WORD;
1985   
1986   if (bytes == -1)
1987     return 0;
1988
1989   if (bytes_left == 0)
1990     return 0;
1991   if (bytes > bytes_left)
1992     return bytes_left;
1993   return 0;
1994 }
1995
1996 /* Variable sized types are passed by reference.  */
1997
1998 static bool
1999 bfin_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2000                         enum machine_mode mode ATTRIBUTE_UNUSED,
2001                         const_tree type, bool named ATTRIBUTE_UNUSED)
2002 {
2003   return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
2004 }
2005
2006 /* Decide whether a type should be returned in memory (true)
2007    or in a register (false).  This is called by the macro
2008    TARGET_RETURN_IN_MEMORY.  */
2009
2010 static bool
2011 bfin_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2012 {
2013   int size = int_size_in_bytes (type);
2014   return size > 2 * UNITS_PER_WORD || size == -1;
2015 }
2016
2017 /* Register in which address to store a structure value
2018    is passed to a function.  */
2019 static rtx
2020 bfin_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
2021                       int incoming ATTRIBUTE_UNUSED)
2022 {
2023   return gen_rtx_REG (Pmode, REG_P0);
2024 }
2025
2026 /* Return true when register may be used to pass function parameters.  */
2027
2028 bool 
2029 function_arg_regno_p (int n)
2030 {
2031   int i;
2032   for (i = 0; arg_regs[i] != -1; i++)
2033     if (n == arg_regs[i])
2034       return true;
2035   return false;
2036 }
2037
2038 /* Returns 1 if OP contains a symbol reference */
2039
2040 int
2041 symbolic_reference_mentioned_p (rtx op)
2042 {
2043   register const char *fmt;
2044   register int i;
2045
2046   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2047     return 1;
2048
2049   fmt = GET_RTX_FORMAT (GET_CODE (op));
2050   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2051     {
2052       if (fmt[i] == 'E')
2053         {
2054           register int j;
2055
2056           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2057             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2058               return 1;
2059         }
2060
2061       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2062         return 1;
2063     }
2064
2065   return 0;
2066 }
2067
2068 /* Decide whether we can make a sibling call to a function.  DECL is the
2069    declaration of the function being targeted by the call and EXP is the
2070    CALL_EXPR representing the call.  */
2071
2072 static bool
2073 bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
2074                               tree exp ATTRIBUTE_UNUSED)
2075 {
2076   struct cgraph_local_info *this_func, *called_func;
2077   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
2078   if (fkind != SUBROUTINE)
2079     return false;
2080   if (!TARGET_ID_SHARED_LIBRARY || TARGET_SEP_DATA)
2081     return true;
2082
2083   /* When compiling for ID shared libraries, can't sibcall a local function
2084      from a non-local function, because the local function thinks it does
2085      not need to reload P5 in the prologue, but the sibcall wil pop P5 in the
2086      sibcall epilogue, and we end up with the wrong value in P5.  */
2087
2088   if (!decl)
2089     /* Not enough information.  */
2090     return false;
2091  
2092   this_func = cgraph_local_info (current_function_decl);
2093   called_func = cgraph_local_info (decl);
2094   return !called_func->local || this_func->local;
2095 }
2096 \f
2097 /* Emit RTL insns to initialize the variable parts of a trampoline at
2098    TRAMP. FNADDR is an RTX for the address of the function's pure
2099    code.  CXT is an RTX for the static chain value for the function.  */
2100
2101 void
2102 initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
2103 {
2104   rtx t1 = copy_to_reg (fnaddr);
2105   rtx t2 = copy_to_reg (cxt);
2106   rtx addr;
2107   int i = 0;
2108
2109   if (TARGET_FDPIC)
2110     {
2111       rtx a = memory_address (Pmode, plus_constant (tramp, 8));
2112       addr = memory_address (Pmode, tramp);
2113       emit_move_insn (gen_rtx_MEM (SImode, addr), a);
2114       i = 8;
2115     }
2116
2117   addr = memory_address (Pmode, plus_constant (tramp, i + 2));
2118   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t1));
2119   emit_insn (gen_ashrsi3 (t1, t1, GEN_INT (16)));
2120   addr = memory_address (Pmode, plus_constant (tramp, i + 6));
2121   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t1));
2122
2123   addr = memory_address (Pmode, plus_constant (tramp, i + 10));
2124   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t2));
2125   emit_insn (gen_ashrsi3 (t2, t2, GEN_INT (16)));
2126   addr = memory_address (Pmode, plus_constant (tramp, i + 14));
2127   emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t2));
2128 }
2129
2130 /* Emit insns to move operands[1] into operands[0].  */
2131
2132 void
2133 emit_pic_move (rtx *operands, enum machine_mode mode ATTRIBUTE_UNUSED)
2134 {
2135   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2136
2137   gcc_assert (!TARGET_FDPIC || !(reload_in_progress || reload_completed));
2138   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
2139     operands[1] = force_reg (SImode, operands[1]);
2140   else
2141     operands[1] = legitimize_pic_address (operands[1], temp,
2142                                           TARGET_FDPIC ? OUR_FDPIC_REG
2143                                           : pic_offset_table_rtx);
2144 }
2145
2146 /* Expand a move operation in mode MODE.  The operands are in OPERANDS.
2147    Returns true if no further code must be generated, false if the caller
2148    should generate an insn to move OPERANDS[1] to OPERANDS[0].  */
2149
2150 bool
2151 expand_move (rtx *operands, enum machine_mode mode)
2152 {
2153   rtx op = operands[1];
2154   if ((TARGET_ID_SHARED_LIBRARY || TARGET_FDPIC)
2155       && SYMBOLIC_CONST (op))
2156     emit_pic_move (operands, mode);
2157   else if (mode == SImode && GET_CODE (op) == CONST
2158            && GET_CODE (XEXP (op, 0)) == PLUS
2159            && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
2160            && !bfin_legitimate_constant_p (op))
2161     {
2162       rtx dest = operands[0];
2163       rtx op0, op1;
2164       gcc_assert (!reload_in_progress && !reload_completed);
2165       op = XEXP (op, 0);
2166       op0 = force_reg (mode, XEXP (op, 0));
2167       op1 = XEXP (op, 1);
2168       if (!insn_data[CODE_FOR_addsi3].operand[2].predicate (op1, mode))
2169         op1 = force_reg (mode, op1);
2170       if (GET_CODE (dest) == MEM)
2171         dest = gen_reg_rtx (mode);
2172       emit_insn (gen_addsi3 (dest, op0, op1));
2173       if (dest == operands[0])
2174         return true;
2175       operands[1] = dest;
2176     }
2177   /* Don't generate memory->memory or constant->memory moves, go through a
2178      register */
2179   else if ((reload_in_progress | reload_completed) == 0
2180            && GET_CODE (operands[0]) == MEM
2181            && GET_CODE (operands[1]) != REG)
2182     operands[1] = force_reg (mode, operands[1]);
2183   return false;
2184 }
2185 \f
2186 /* Split one or more DImode RTL references into pairs of SImode
2187    references.  The RTL can be REG, offsettable MEM, integer constant, or
2188    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
2189    split and "num" is its length.  lo_half and hi_half are output arrays
2190    that parallel "operands".  */
2191
2192 void
2193 split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
2194 {
2195   while (num--)
2196     {
2197       rtx op = operands[num];
2198
2199       /* simplify_subreg refuse to split volatile memory addresses,
2200          but we still have to handle it.  */
2201       if (GET_CODE (op) == MEM)
2202         {
2203           lo_half[num] = adjust_address (op, SImode, 0);
2204           hi_half[num] = adjust_address (op, SImode, 4);
2205         }
2206       else
2207         {
2208           lo_half[num] = simplify_gen_subreg (SImode, op,
2209                                               GET_MODE (op) == VOIDmode
2210                                               ? DImode : GET_MODE (op), 0);
2211           hi_half[num] = simplify_gen_subreg (SImode, op,
2212                                               GET_MODE (op) == VOIDmode
2213                                               ? DImode : GET_MODE (op), 4);
2214         }
2215     }
2216 }
2217 \f
2218 bool
2219 bfin_longcall_p (rtx op, int call_cookie)
2220 {
2221   gcc_assert (GET_CODE (op) == SYMBOL_REF);
2222   if (SYMBOL_REF_WEAK (op))
2223     return 1;
2224   if (call_cookie & CALL_SHORT)
2225     return 0;
2226   if (call_cookie & CALL_LONG)
2227     return 1;
2228   if (TARGET_LONG_CALLS)
2229     return 1;
2230   return 0;
2231 }
2232
2233 /* Expand a call instruction.  FNADDR is the call target, RETVAL the return value.
2234    COOKIE is a CONST_INT holding the call_cookie prepared init_cumulative_args.
2235    SIBCALL is nonzero if this is a sibling call.  */
2236
2237 void
2238 bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall)
2239 {
2240   rtx use = NULL, call;
2241   rtx callee = XEXP (fnaddr, 0);
2242   int nelts = 3;
2243   rtx pat;
2244   rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REGNO);
2245   rtx retsreg = gen_rtx_REG (Pmode, REG_RETS);
2246   int n;
2247
2248   /* In an untyped call, we can get NULL for operand 2.  */
2249   if (cookie == NULL_RTX)
2250     cookie = const0_rtx;
2251
2252   /* Static functions and indirect calls don't need the pic register.  */
2253   if (!TARGET_FDPIC && flag_pic
2254       && GET_CODE (callee) == SYMBOL_REF
2255       && !SYMBOL_REF_LOCAL_P (callee))
2256     use_reg (&use, pic_offset_table_rtx);
2257
2258   if (TARGET_FDPIC)
2259     {
2260       int caller_in_sram, callee_in_sram;
2261
2262       /* 0 is not in sram, 1 is in L1 sram, 2 is in L2 sram.  */
2263       caller_in_sram = callee_in_sram = 0;
2264
2265       if (lookup_attribute ("l1_text",
2266                             DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE)
2267         caller_in_sram = 1;
2268       else if (lookup_attribute ("l2",
2269                                  DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE)
2270         caller_in_sram = 2;
2271
2272       if (GET_CODE (callee) == SYMBOL_REF
2273           && SYMBOL_REF_DECL (callee) && DECL_P (SYMBOL_REF_DECL (callee)))
2274         {
2275           if (lookup_attribute
2276               ("l1_text",
2277                DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE)
2278             callee_in_sram = 1;
2279           else if (lookup_attribute
2280                    ("l2",
2281                     DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE)
2282             callee_in_sram = 2;
2283         }
2284
2285       if (GET_CODE (callee) != SYMBOL_REF
2286           || bfin_longcall_p (callee, INTVAL (cookie))
2287           || (GET_CODE (callee) == SYMBOL_REF
2288               && !SYMBOL_REF_LOCAL_P (callee)
2289               && TARGET_INLINE_PLT)
2290           || caller_in_sram != callee_in_sram
2291           || (caller_in_sram && callee_in_sram
2292               && (GET_CODE (callee) != SYMBOL_REF
2293                   || !SYMBOL_REF_LOCAL_P (callee))))
2294         {
2295           rtx addr = callee;
2296           if (! address_operand (addr, Pmode))
2297             addr = force_reg (Pmode, addr);
2298
2299           fnaddr = gen_reg_rtx (SImode);
2300           emit_insn (gen_load_funcdescsi (fnaddr, addr));
2301           fnaddr = gen_rtx_MEM (Pmode, fnaddr);
2302
2303           picreg = gen_reg_rtx (SImode);
2304           emit_insn (gen_load_funcdescsi (picreg,
2305                                           plus_constant (addr, 4)));
2306         }
2307
2308       nelts++;
2309     }
2310   else if ((!register_no_elim_operand (callee, Pmode)
2311             && GET_CODE (callee) != SYMBOL_REF)
2312            || (GET_CODE (callee) == SYMBOL_REF
2313                && ((TARGET_ID_SHARED_LIBRARY && !TARGET_LEAF_ID_SHARED_LIBRARY)
2314                    || bfin_longcall_p (callee, INTVAL (cookie)))))
2315     {
2316       callee = copy_to_mode_reg (Pmode, callee);
2317       fnaddr = gen_rtx_MEM (Pmode, callee);
2318     }
2319   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
2320
2321   if (retval)
2322     call = gen_rtx_SET (VOIDmode, retval, call);
2323
2324   pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nelts));
2325   n = 0;
2326   XVECEXP (pat, 0, n++) = call;
2327   if (TARGET_FDPIC)
2328     XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, picreg);
2329   XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, cookie);
2330   if (sibcall)
2331     XVECEXP (pat, 0, n++) = gen_rtx_RETURN (VOIDmode);
2332   else
2333     XVECEXP (pat, 0, n++) = gen_rtx_CLOBBER (VOIDmode, retsreg);
2334   call = emit_call_insn (pat);
2335   if (use)
2336     CALL_INSN_FUNCTION_USAGE (call) = use;
2337 }
2338 \f
2339 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE.  */
2340
2341 int
2342 hard_regno_mode_ok (int regno, enum machine_mode mode)
2343 {
2344   /* Allow only dregs to store value of mode HI or QI */
2345   enum reg_class rclass = REGNO_REG_CLASS (regno);
2346
2347   if (mode == CCmode)
2348     return 0;
2349
2350   if (mode == V2HImode)
2351     return D_REGNO_P (regno);
2352   if (rclass == CCREGS)
2353     return mode == BImode;
2354   if (mode == PDImode || mode == V2PDImode)
2355     return regno == REG_A0 || regno == REG_A1;
2356
2357   /* Allow all normal 32-bit regs, except REG_M3, in case regclass ever comes
2358      up with a bad register class (such as ALL_REGS) for DImode.  */
2359   if (mode == DImode)
2360     return regno < REG_M3;
2361
2362   if (mode == SImode
2363       && TEST_HARD_REG_BIT (reg_class_contents[PROLOGUE_REGS], regno))
2364     return 1;
2365
2366   return TEST_HARD_REG_BIT (reg_class_contents[MOST_REGS], regno);
2367 }
2368
2369 /* Implements target hook vector_mode_supported_p.  */
2370
2371 static bool
2372 bfin_vector_mode_supported_p (enum machine_mode mode)
2373 {
2374   return mode == V2HImode;
2375 }
2376
2377 /* Return the cost of moving data from a register in class CLASS1 to
2378    one in class CLASS2.  A cost of 2 is the default.  */
2379
2380 int
2381 bfin_register_move_cost (enum machine_mode mode,
2382                          enum reg_class class1, enum reg_class class2)
2383 {
2384   /* These need secondary reloads, so they're more expensive.  */
2385   if ((class1 == CCREGS && !reg_class_subset_p (class2, DREGS))
2386       || (class2 == CCREGS && !reg_class_subset_p (class1, DREGS)))
2387     return 4;
2388
2389   /* If optimizing for size, always prefer reg-reg over reg-memory moves.  */
2390   if (optimize_size)
2391     return 2;
2392
2393   if (GET_MODE_CLASS (mode) == MODE_INT)
2394     {
2395       /* Discourage trying to use the accumulators.  */
2396       if (TEST_HARD_REG_BIT (reg_class_contents[class1], REG_A0)
2397           || TEST_HARD_REG_BIT (reg_class_contents[class1], REG_A1)
2398           || TEST_HARD_REG_BIT (reg_class_contents[class2], REG_A0)
2399           || TEST_HARD_REG_BIT (reg_class_contents[class2], REG_A1))
2400         return 20;
2401     }
2402   return 2;
2403 }
2404
2405 /* Return the cost of moving data of mode M between a
2406    register and memory.  A value of 2 is the default; this cost is
2407    relative to those in `REGISTER_MOVE_COST'.
2408
2409    ??? In theory L1 memory has single-cycle latency.  We should add a switch
2410    that tells the compiler whether we expect to use only L1 memory for the
2411    program; it'll make the costs more accurate.  */
2412
2413 int
2414 bfin_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
2415                        enum reg_class rclass,
2416                        int in ATTRIBUTE_UNUSED)
2417 {
2418   /* Make memory accesses slightly more expensive than any register-register
2419      move.  Also, penalize non-DP registers, since they need secondary
2420      reloads to load and store.  */
2421   if (! reg_class_subset_p (rclass, DPREGS))
2422     return 10;
2423
2424   return 8;
2425 }
2426
2427 /* Inform reload about cases where moving X with a mode MODE to a register in
2428    RCLASS requires an extra scratch register.  Return the class needed for the
2429    scratch register.  */
2430
2431 static enum reg_class
2432 bfin_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
2433                        enum machine_mode mode, secondary_reload_info *sri)
2434 {
2435   /* If we have HImode or QImode, we can only use DREGS as secondary registers;
2436      in most other cases we can also use PREGS.  */
2437   enum reg_class default_class = GET_MODE_SIZE (mode) >= 4 ? DPREGS : DREGS;
2438   enum reg_class x_class = NO_REGS;
2439   enum rtx_code code = GET_CODE (x);
2440
2441   if (code == SUBREG)
2442     x = SUBREG_REG (x), code = GET_CODE (x);
2443   if (REG_P (x))
2444     {
2445       int regno = REGNO (x);
2446       if (regno >= FIRST_PSEUDO_REGISTER)
2447         regno = reg_renumber[regno];
2448
2449       if (regno == -1)
2450         code = MEM;
2451       else
2452         x_class = REGNO_REG_CLASS (regno);
2453     }
2454
2455   /* We can be asked to reload (plus (FP) (large_constant)) into a DREG.
2456      This happens as a side effect of register elimination, and we need
2457      a scratch register to do it.  */
2458   if (fp_plus_const_operand (x, mode))
2459     {
2460       rtx op2 = XEXP (x, 1);
2461       int large_constant_p = ! satisfies_constraint_Ks7 (op2);
2462
2463       if (rclass == PREGS || rclass == PREGS_CLOBBERED)
2464         return NO_REGS;
2465       /* If destination is a DREG, we can do this without a scratch register
2466          if the constant is valid for an add instruction.  */
2467       if ((rclass == DREGS || rclass == DPREGS)
2468           && ! large_constant_p)
2469         return NO_REGS;
2470       /* Reloading to anything other than a DREG?  Use a PREG scratch
2471          register.  */
2472       sri->icode = CODE_FOR_reload_insi;
2473       return NO_REGS;
2474     }
2475
2476   /* Data can usually be moved freely between registers of most classes.
2477      AREGS are an exception; they can only move to or from another register
2478      in AREGS or one in DREGS.  They can also be assigned the constant 0.  */
2479   if (x_class == AREGS || x_class == EVEN_AREGS || x_class == ODD_AREGS)
2480     return (rclass == DREGS || rclass == AREGS || rclass == EVEN_AREGS
2481             || rclass == ODD_AREGS
2482             ? NO_REGS : DREGS);
2483
2484   if (rclass == AREGS || rclass == EVEN_AREGS || rclass == ODD_AREGS)
2485     {
2486       if (code == MEM)
2487         {
2488           sri->icode = in_p ? CODE_FOR_reload_inpdi : CODE_FOR_reload_outpdi;
2489           return NO_REGS;
2490         }
2491
2492       if (x != const0_rtx && x_class != DREGS)
2493         {
2494           return DREGS;
2495         }
2496       else
2497         return NO_REGS;
2498     }
2499
2500   /* CCREGS can only be moved from/to DREGS.  */
2501   if (rclass == CCREGS && x_class != DREGS)
2502     return DREGS;
2503   if (x_class == CCREGS && rclass != DREGS)
2504     return DREGS;
2505
2506   /* All registers other than AREGS can load arbitrary constants.  The only
2507      case that remains is MEM.  */
2508   if (code == MEM)
2509     if (! reg_class_subset_p (rclass, default_class))
2510       return default_class;
2511
2512   return NO_REGS;
2513 }
2514 \f
2515 /* Implement TARGET_HANDLE_OPTION.  */
2516
2517 static bool
2518 bfin_handle_option (size_t code, const char *arg, int value)
2519 {
2520   switch (code)
2521     {
2522     case OPT_mshared_library_id_:
2523       if (value > MAX_LIBRARY_ID)
2524         error ("-mshared-library-id=%s is not between 0 and %d",
2525                arg, MAX_LIBRARY_ID);
2526       bfin_lib_id_given = 1;
2527       return true;
2528
2529     case OPT_mcpu_:
2530       {
2531         const char *p, *q;
2532         int i;
2533
2534         i = 0;
2535         while ((p = bfin_cpus[i].name) != NULL)
2536           {
2537             if (strncmp (arg, p, strlen (p)) == 0)
2538               break;
2539             i++;
2540           }
2541
2542         if (p == NULL)
2543           {
2544             error ("-mcpu=%s is not valid", arg);
2545             return false;
2546           }
2547
2548         bfin_cpu_type = bfin_cpus[i].type;
2549
2550         q = arg + strlen (p);
2551
2552         if (*q == '\0')
2553           {
2554             bfin_si_revision = bfin_cpus[i].si_revision;
2555             bfin_workarounds |= bfin_cpus[i].workarounds;
2556           }
2557         else if (strcmp (q, "-none") == 0)
2558           bfin_si_revision = -1;
2559         else if (strcmp (q, "-any") == 0)
2560           {
2561             bfin_si_revision = 0xffff;
2562             while (bfin_cpus[i].type == bfin_cpu_type)
2563               {
2564                 bfin_workarounds |= bfin_cpus[i].workarounds;
2565                 i++;
2566               }
2567           }
2568         else
2569           {
2570             unsigned int si_major, si_minor;
2571             int rev_len, n;
2572
2573             rev_len = strlen (q);
2574
2575             if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2
2576                 || n != rev_len
2577                 || si_major > 0xff || si_minor > 0xff)
2578               {
2579               invalid_silicon_revision:
2580                 error ("-mcpu=%s has invalid silicon revision", arg);
2581                 return false;
2582               }
2583
2584             bfin_si_revision = (si_major << 8) | si_minor;
2585
2586             while (bfin_cpus[i].type == bfin_cpu_type
2587                    && bfin_cpus[i].si_revision != bfin_si_revision)
2588               i++;
2589
2590             if (bfin_cpus[i].type != bfin_cpu_type)
2591               goto invalid_silicon_revision;
2592
2593             bfin_workarounds |= bfin_cpus[i].workarounds;
2594           }
2595
2596         return true;
2597       }
2598
2599     default:
2600       return true;
2601     }
2602 }
2603
2604 static struct machine_function *
2605 bfin_init_machine_status (void)
2606 {
2607   struct machine_function *f;
2608
2609   f = GGC_CNEW (struct machine_function);
2610
2611   return f;
2612 }
2613
2614 /* Implement the macro OVERRIDE_OPTIONS.  */
2615
2616 void
2617 override_options (void)
2618 {
2619   /* If processor type is not specified, enable all workarounds.  */
2620   if (bfin_cpu_type == BFIN_CPU_UNKNOWN)
2621     {
2622       int i;
2623
2624       for (i = 0; bfin_cpus[i].name != NULL; i++)
2625         bfin_workarounds |= bfin_cpus[i].workarounds;
2626
2627       bfin_si_revision = 0xffff;
2628     }
2629
2630   if (bfin_csync_anomaly == 1)
2631     bfin_workarounds |= WA_SPECULATIVE_SYNCS;
2632   else if (bfin_csync_anomaly == 0)
2633     bfin_workarounds &= ~WA_SPECULATIVE_SYNCS;
2634
2635   if (bfin_specld_anomaly == 1)
2636     bfin_workarounds |= WA_SPECULATIVE_LOADS;
2637   else if (bfin_specld_anomaly == 0)
2638     bfin_workarounds &= ~WA_SPECULATIVE_LOADS;
2639
2640   if (TARGET_OMIT_LEAF_FRAME_POINTER)
2641     flag_omit_frame_pointer = 1;
2642
2643   /* Library identification */
2644   if (bfin_lib_id_given && ! TARGET_ID_SHARED_LIBRARY)
2645     error ("-mshared-library-id= specified without -mid-shared-library");
2646
2647   if (stack_limit_rtx && TARGET_STACK_CHECK_L1)
2648     error ("Can't use multiple stack checking methods together.");
2649
2650   if (TARGET_ID_SHARED_LIBRARY && TARGET_FDPIC)
2651     error ("ID shared libraries and FD-PIC mode can't be used together.");
2652
2653   /* Don't allow the user to specify -mid-shared-library and -msep-data
2654      together, as it makes little sense from a user's point of view...  */
2655   if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
2656     error ("cannot specify both -msep-data and -mid-shared-library");
2657   /* ... internally, however, it's nearly the same.  */
2658   if (TARGET_SEP_DATA)
2659     target_flags |= MASK_ID_SHARED_LIBRARY | MASK_LEAF_ID_SHARED_LIBRARY;
2660
2661   if (TARGET_ID_SHARED_LIBRARY && flag_pic == 0)
2662     flag_pic = 1;
2663
2664   /* There is no single unaligned SI op for PIC code.  Sometimes we
2665      need to use ".4byte" and sometimes we need to use ".picptr".
2666      See bfin_assemble_integer for details.  */
2667   if (TARGET_FDPIC)
2668     targetm.asm_out.unaligned_op.si = 0;
2669
2670   /* Silently turn off flag_pic if not doing FDPIC or ID shared libraries,
2671      since we don't support it and it'll just break.  */
2672   if (flag_pic && !TARGET_FDPIC && !TARGET_ID_SHARED_LIBRARY)
2673     flag_pic = 0;
2674
2675   if (TARGET_MULTICORE && bfin_cpu_type != BFIN_CPU_BF561)
2676     error ("-mmulticore can only be used with BF561");
2677
2678   if (TARGET_COREA && !TARGET_MULTICORE)
2679     error ("-mcorea should be used with -mmulticore");
2680
2681   if (TARGET_COREB && !TARGET_MULTICORE)
2682     error ("-mcoreb should be used with -mmulticore");
2683
2684   if (TARGET_COREA && TARGET_COREB)
2685     error ("-mcorea and -mcoreb can't be used together");
2686
2687   flag_schedule_insns = 0;
2688
2689   /* Passes after sched2 can break the helpful TImode annotations that
2690      haifa-sched puts on every insn.  Just do scheduling in reorg.  */
2691   bfin_flag_schedule_insns2 = flag_schedule_insns_after_reload;
2692   flag_schedule_insns_after_reload = 0;
2693
2694   init_machine_status = bfin_init_machine_status;
2695 }
2696
2697 /* Return the destination address of BRANCH.
2698    We need to use this instead of get_attr_length, because the
2699    cbranch_with_nops pattern conservatively sets its length to 6, and
2700    we still prefer to use shorter sequences.  */
2701
2702 static int
2703 branch_dest (rtx branch)
2704 {
2705   rtx dest;
2706   int dest_uid;
2707   rtx pat = PATTERN (branch);
2708   if (GET_CODE (pat) == PARALLEL)
2709     pat = XVECEXP (pat, 0, 0);
2710   dest = SET_SRC (pat);
2711   if (GET_CODE (dest) == IF_THEN_ELSE)
2712     dest = XEXP (dest, 1);
2713   dest = XEXP (dest, 0);
2714   dest_uid = INSN_UID (dest);
2715   return INSN_ADDRESSES (dest_uid);
2716 }
2717
2718 /* Return nonzero if INSN is annotated with a REG_BR_PROB note that indicates
2719    it's a branch that's predicted taken.  */
2720
2721 static int
2722 cbranch_predicted_taken_p (rtx insn)
2723 {
2724   rtx x = find_reg_note (insn, REG_BR_PROB, 0);
2725
2726   if (x)
2727     {
2728       int pred_val = INTVAL (XEXP (x, 0));
2729
2730       return pred_val >= REG_BR_PROB_BASE / 2;
2731     }
2732
2733   return 0;
2734 }
2735
2736 /* Templates for use by asm_conditional_branch.  */
2737
2738 static const char *ccbranch_templates[][3] = {
2739   { "if !cc jump %3;",  "if cc jump 4 (bp); jump.s %3;",  "if cc jump 6 (bp); jump.l %3;" },
2740   { "if cc jump %3;",   "if !cc jump 4 (bp); jump.s %3;", "if !cc jump 6 (bp); jump.l %3;" },
2741   { "if !cc jump %3 (bp);",  "if cc jump 4; jump.s %3;",  "if cc jump 6; jump.l %3;" },
2742   { "if cc jump %3 (bp);",  "if !cc jump 4; jump.s %3;",  "if !cc jump 6; jump.l %3;" },
2743 };
2744
2745 /* Output INSN, which is a conditional branch instruction with operands
2746    OPERANDS.
2747
2748    We deal with the various forms of conditional branches that can be generated
2749    by bfin_reorg to prevent the hardware from doing speculative loads, by
2750    - emitting a sufficient number of nops, if N_NOPS is nonzero, or
2751    - always emitting the branch as predicted taken, if PREDICT_TAKEN is true.
2752    Either of these is only necessary if the branch is short, otherwise the
2753    template we use ends in an unconditional jump which flushes the pipeline
2754    anyway.  */
2755
2756 void
2757 asm_conditional_branch (rtx insn, rtx *operands, int n_nops, int predict_taken)
2758 {
2759   int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
2760   /* Note : offset for instructions like if cc jmp; jump.[sl] offset
2761             is to be taken from start of if cc rather than jump.
2762             Range for jump.s is (-4094, 4096) instead of (-4096, 4094)
2763   */
2764   int len = (offset >= -1024 && offset <= 1022 ? 0
2765              : offset >= -4094 && offset <= 4096 ? 1
2766              : 2);
2767   int bp = predict_taken && len == 0 ? 1 : cbranch_predicted_taken_p (insn);
2768   int idx = (bp << 1) | (GET_CODE (operands[0]) == EQ ? BRF : BRT);
2769   output_asm_insn (ccbranch_templates[idx][len], operands);
2770   gcc_assert (n_nops == 0 || !bp);
2771   if (len == 0)
2772     while (n_nops-- > 0)
2773       output_asm_insn ("nop;", NULL);
2774 }
2775
2776 /* Emit rtl for a comparison operation CMP in mode MODE.  Operands have been
2777    stored in bfin_compare_op0 and bfin_compare_op1 already.  */
2778
2779 rtx
2780 bfin_gen_compare (rtx cmp, enum machine_mode mode ATTRIBUTE_UNUSED)
2781 {
2782   enum rtx_code code1, code2;
2783   rtx op0 = XEXP (cmp, 0), op1 = XEXP (cmp, 1);
2784   rtx tem = bfin_cc_rtx;
2785   enum rtx_code code = GET_CODE (cmp);
2786
2787   /* If we have a BImode input, then we already have a compare result, and
2788      do not need to emit another comparison.  */
2789   if (GET_MODE (op0) == BImode)
2790     {
2791       gcc_assert ((code == NE || code == EQ) && op1 == const0_rtx);
2792       tem = op0, code2 = code;
2793     }
2794   else
2795     {
2796       switch (code) {
2797         /* bfin has these conditions */
2798       case EQ:
2799       case LT:
2800       case LE:
2801       case LEU:
2802       case LTU:
2803         code1 = code;
2804         code2 = NE;
2805         break;
2806       default:
2807         code1 = reverse_condition (code);
2808         code2 = EQ;
2809         break;
2810       }
2811       emit_insn (gen_rtx_SET (VOIDmode, tem,
2812                               gen_rtx_fmt_ee (code1, BImode, op0, op1)));
2813     }
2814
2815   return gen_rtx_fmt_ee (code2, BImode, tem, CONST0_RTX (BImode));
2816 }
2817 \f
2818 /* Return nonzero iff C has exactly one bit set if it is interpreted
2819    as a 32-bit constant.  */
2820
2821 int
2822 log2constp (unsigned HOST_WIDE_INT c)
2823 {
2824   c &= 0xFFFFFFFF;
2825   return c != 0 && (c & (c-1)) == 0;
2826 }
2827
2828 /* Returns the number of consecutive least significant zeros in the binary
2829    representation of *V.
2830    We modify *V to contain the original value arithmetically shifted right by
2831    the number of zeroes.  */
2832
2833 static int
2834 shiftr_zero (HOST_WIDE_INT *v)
2835 {
2836   unsigned HOST_WIDE_INT tmp = *v;
2837   unsigned HOST_WIDE_INT sgn;
2838   int n = 0;
2839
2840   if (tmp == 0)
2841     return 0;
2842
2843   sgn = tmp & ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1));
2844   while ((tmp & 0x1) == 0 && n <= 32)
2845     {
2846       tmp = (tmp >> 1) | sgn;
2847       n++;
2848     }
2849   *v = tmp;
2850   return n;
2851 }
2852
2853 /* After reload, split the load of an immediate constant.  OPERANDS are the
2854    operands of the movsi_insn pattern which we are splitting.  We return
2855    nonzero if we emitted a sequence to load the constant, zero if we emitted
2856    nothing because we want to use the splitter's default sequence.  */
2857
2858 int
2859 split_load_immediate (rtx operands[])
2860 {
2861   HOST_WIDE_INT val = INTVAL (operands[1]);
2862   HOST_WIDE_INT tmp;
2863   HOST_WIDE_INT shifted = val;
2864   HOST_WIDE_INT shifted_compl = ~val;
2865   int num_zero = shiftr_zero (&shifted);
2866   int num_compl_zero = shiftr_zero (&shifted_compl);
2867   unsigned int regno = REGNO (operands[0]);
2868
2869   /* This case takes care of single-bit set/clear constants, which we could
2870      also implement with BITSET/BITCLR.  */
2871   if (num_zero
2872       && shifted >= -32768 && shifted < 65536
2873       && (D_REGNO_P (regno)
2874           || (regno >= REG_P0 && regno <= REG_P7 && num_zero <= 2)))
2875     {
2876       emit_insn (gen_movsi (operands[0], GEN_INT (shifted)));
2877       emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (num_zero)));
2878       return 1;
2879     }
2880
2881   tmp = val & 0xFFFF;
2882   tmp |= -(tmp & 0x8000);
2883
2884   /* If high word has one bit set or clear, try to use a bit operation.  */
2885   if (D_REGNO_P (regno))
2886     {
2887       if (log2constp (val & 0xFFFF0000))
2888         {
2889           emit_insn (gen_movsi (operands[0], GEN_INT (val & 0xFFFF)));
2890           emit_insn (gen_iorsi3 (operands[0], operands[0], GEN_INT (val & 0xFFFF0000)));
2891           return 1;
2892         }
2893       else if (log2constp (val | 0xFFFF) && (val & 0x8000) != 0)
2894         {
2895           emit_insn (gen_movsi (operands[0], GEN_INT (tmp)));
2896           emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (val | 0xFFFF)));
2897         }
2898     }
2899
2900   if (D_REGNO_P (regno))
2901     {
2902       if (tmp >= -64 && tmp <= 63)
2903         {
2904           emit_insn (gen_movsi (operands[0], GEN_INT (tmp)));
2905           emit_insn (gen_movstricthi_high (operands[0], GEN_INT (val & -65536)));
2906           return 1;
2907         }
2908
2909       if ((val & 0xFFFF0000) == 0)
2910         {
2911           emit_insn (gen_movsi (operands[0], const0_rtx));
2912           emit_insn (gen_movsi_low (operands[0], operands[0], operands[1]));
2913           return 1;
2914         }
2915
2916       if ((val & 0xFFFF0000) == 0xFFFF0000)
2917         {
2918           emit_insn (gen_movsi (operands[0], constm1_rtx));
2919           emit_insn (gen_movsi_low (operands[0], operands[0], operands[1]));
2920           return 1;
2921         }
2922     }
2923
2924   /* Need DREGs for the remaining case.  */
2925   if (regno > REG_R7)
2926     return 0;
2927
2928   if (optimize_size
2929       && num_compl_zero && shifted_compl >= -64 && shifted_compl <= 63)
2930     {
2931       /* If optimizing for size, generate a sequence that has more instructions
2932          but is shorter.  */
2933       emit_insn (gen_movsi (operands[0], GEN_INT (shifted_compl)));
2934       emit_insn (gen_ashlsi3 (operands[0], operands[0],
2935                               GEN_INT (num_compl_zero)));
2936       emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
2937       return 1;
2938     }
2939   return 0;
2940 }
2941 \f
2942 /* Return true if the legitimate memory address for a memory operand of mode
2943    MODE.  Return false if not.  */
2944
2945 static bool
2946 bfin_valid_add (enum machine_mode mode, HOST_WIDE_INT value)
2947 {
2948   unsigned HOST_WIDE_INT v = value > 0 ? value : -value;
2949   int sz = GET_MODE_SIZE (mode);
2950   int shift = sz == 1 ? 0 : sz == 2 ? 1 : 2;
2951   /* The usual offsettable_memref machinery doesn't work so well for this
2952      port, so we deal with the problem here.  */
2953   if (value > 0 && sz == 8)
2954     v += 4;
2955   return (v & ~(0x7fff << shift)) == 0;
2956 }
2957
2958 static bool
2959 bfin_valid_reg_p (unsigned int regno, int strict, enum machine_mode mode,
2960                   enum rtx_code outer_code)
2961 {
2962   if (strict)
2963     return REGNO_OK_FOR_BASE_STRICT_P (regno, mode, outer_code, SCRATCH);
2964   else
2965     return REGNO_OK_FOR_BASE_NONSTRICT_P (regno, mode, outer_code, SCRATCH);
2966 }
2967
2968 /* Recognize an RTL expression that is a valid memory address for an
2969    instruction.  The MODE argument is the machine mode for the MEM expression
2970    that wants to use this address. 
2971
2972    Blackfin addressing modes are as follows:
2973
2974       [preg]
2975       [preg + imm16]
2976
2977       B [ Preg + uimm15 ]
2978       W [ Preg + uimm16m2 ]
2979       [ Preg + uimm17m4 ] 
2980
2981       [preg++]
2982       [preg--]
2983       [--sp]
2984 */
2985
2986 static bool
2987 bfin_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
2988 {
2989   switch (GET_CODE (x)) {
2990   case REG:
2991     if (bfin_valid_reg_p (REGNO (x), strict, mode, MEM))
2992       return true;
2993     break;
2994   case PLUS:
2995     if (REG_P (XEXP (x, 0))
2996         && bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, PLUS)
2997         && ((GET_CODE (XEXP (x, 1)) == UNSPEC && mode == SImode)
2998             || (GET_CODE (XEXP (x, 1)) == CONST_INT
2999                 && bfin_valid_add (mode, INTVAL (XEXP (x, 1))))))
3000       return true;
3001     break;
3002   case POST_INC:
3003   case POST_DEC:
3004     if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
3005         && REG_P (XEXP (x, 0))
3006         && bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, POST_INC))
3007       return true;
3008   case PRE_DEC:
3009     if (LEGITIMATE_MODE_FOR_AUTOINC_P (mode)
3010         && XEXP (x, 0) == stack_pointer_rtx
3011         && REG_P (XEXP (x, 0))
3012         && bfin_valid_reg_p (REGNO (XEXP (x, 0)), strict, mode, PRE_DEC))
3013       return true;
3014     break;
3015   default:
3016     break;
3017   }
3018   return false;
3019 }
3020
3021 /* Decide whether we can force certain constants to memory.  If we
3022    decide we can't, the caller should be able to cope with it in
3023    another way.  */
3024
3025 static bool
3026 bfin_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
3027 {
3028   /* We have only one class of non-legitimate constants, and our movsi
3029      expander knows how to handle them.  Dropping these constants into the
3030      data section would only shift the problem - we'd still get relocs
3031      outside the object, in the data section rather than the text section.  */
3032   return true;
3033 }
3034
3035 /* Ensure that for any constant of the form symbol + offset, the offset
3036    remains within the object.  Any other constants are ok.
3037    This ensures that flat binaries never have to deal with relocations
3038    crossing section boundaries.  */
3039
3040 bool
3041 bfin_legitimate_constant_p (rtx x)
3042 {
3043   rtx sym;
3044   HOST_WIDE_INT offset;
3045
3046   if (GET_CODE (x) != CONST)
3047     return true;
3048
3049   x = XEXP (x, 0);
3050   gcc_assert (GET_CODE (x) == PLUS);
3051
3052   sym = XEXP (x, 0);
3053   x = XEXP (x, 1);
3054   if (GET_CODE (sym) != SYMBOL_REF
3055       || GET_CODE (x) != CONST_INT)
3056     return true;
3057   offset = INTVAL (x);
3058
3059   if (SYMBOL_REF_DECL (sym) == 0)
3060     return true;
3061   if (offset < 0
3062       || offset >= int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (sym))))
3063     return false;
3064
3065   return true;
3066 }
3067
3068 static bool
3069 bfin_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
3070 {
3071   int cost2 = COSTS_N_INSNS (1);
3072   rtx op0, op1;
3073
3074   switch (code)
3075     {
3076     case CONST_INT:
3077       if (outer_code == SET || outer_code == PLUS)
3078         *total = satisfies_constraint_Ks7 (x) ? 0 : cost2;
3079       else if (outer_code == AND)
3080         *total = log2constp (~INTVAL (x)) ? 0 : cost2;
3081       else if (outer_code == LE || outer_code == LT || outer_code == EQ)
3082         *total = (INTVAL (x) >= -4 && INTVAL (x) <= 3) ? 0 : cost2;
3083       else if (outer_code == LEU || outer_code == LTU)
3084         *total = (INTVAL (x) >= 0 && INTVAL (x) <= 7) ? 0 : cost2;
3085       else if (outer_code == MULT)
3086         *total = (INTVAL (x) == 2 || INTVAL (x) == 4) ? 0 : cost2;
3087       else if (outer_code == ASHIFT && (INTVAL (x) == 1 || INTVAL (x) == 2))
3088         *total = 0;
3089       else if (outer_code == ASHIFT || outer_code == ASHIFTRT
3090                || outer_code == LSHIFTRT)
3091         *total = (INTVAL (x) >= 0 && INTVAL (x) <= 31) ? 0 : cost2;
3092       else if (outer_code == IOR || outer_code == XOR)
3093         *total = (INTVAL (x) & (INTVAL (x) - 1)) == 0 ? 0 : cost2;
3094       else
3095         *total = cost2;
3096       return true;
3097
3098     case CONST:
3099     case LABEL_REF:
3100     case SYMBOL_REF:
3101     case CONST_DOUBLE:
3102       *total = COSTS_N_INSNS (2);
3103       return true;
3104
3105     case PLUS:
3106       op0 = XEXP (x, 0);
3107       op1 = XEXP (x, 1);
3108       if (GET_MODE (x) == SImode)
3109         {
3110           if (GET_CODE (op0) == MULT
3111               && GET_CODE (XEXP (op0, 1)) == CONST_INT)
3112             {
3113               HOST_WIDE_INT val = INTVAL (XEXP (op0, 1));
3114               if (val == 2 || val == 4)
3115                 {
3116                   *total = cost2;
3117                   *total += rtx_cost (XEXP (op0, 0), outer_code, speed);
3118                   *total += rtx_cost (op1, outer_code, speed);
3119                   return true;
3120                 }
3121             }
3122           *total = cost2;
3123           if (GET_CODE (op0) != REG
3124               && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
3125             *total += rtx_cost (op0, SET, speed);
3126 #if 0 /* We'd like to do this for accuracy, but it biases the loop optimizer
3127          towards creating too many induction variables.  */
3128           if (!reg_or_7bit_operand (op1, SImode))
3129             *total += rtx_cost (op1, SET, speed);
3130 #endif
3131         }
3132       else if (GET_MODE (x) == DImode)
3133         {
3134           *total = 6 * cost2;
3135           if (GET_CODE (op1) != CONST_INT
3136               || !satisfies_constraint_Ks7 (op1))
3137             *total += rtx_cost (op1, PLUS, speed);
3138           if (GET_CODE (op0) != REG
3139               && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
3140             *total += rtx_cost (op0, PLUS, speed);
3141         }
3142       return true;
3143
3144     case MINUS:
3145       if (GET_MODE (x) == DImode)
3146         *total = 6 * cost2;
3147       else
3148         *total = cost2;
3149       return true;
3150       
3151     case ASHIFT: 
3152     case ASHIFTRT:
3153     case LSHIFTRT:
3154       if (GET_MODE (x) == DImode)
3155         *total = 6 * cost2;
3156       else
3157         *total = cost2;
3158
3159       op0 = XEXP (x, 0);
3160       op1 = XEXP (x, 1);
3161       if (GET_CODE (op0) != REG
3162           && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
3163         *total += rtx_cost (op0, code, speed);
3164
3165       return true;
3166           
3167     case IOR:
3168     case AND:
3169     case XOR:
3170       op0 = XEXP (x, 0);
3171       op1 = XEXP (x, 1);
3172
3173       /* Handle special cases of IOR: rotates, ALIGN insns, movstricthi_high.  */
3174       if (code == IOR)
3175         {
3176           if ((GET_CODE (op0) == LSHIFTRT && GET_CODE (op1) == ASHIFT)
3177               || (GET_CODE (op0) == ASHIFT && GET_CODE (op1) == ZERO_EXTEND)
3178               || (GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT)
3179               || (GET_CODE (op0) == AND && GET_CODE (op1) == CONST_INT))
3180             {
3181               *total = cost2;
3182               return true;
3183             }
3184         }
3185
3186       if (GET_CODE (op0) != REG
3187           && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
3188         *total += rtx_cost (op0, code, speed);
3189
3190       if (GET_MODE (x) == DImode)
3191         {
3192           *total = 2 * cost2;
3193           return true;
3194         }
3195       *total = cost2;
3196       if (GET_MODE (x) != SImode)
3197         return true;
3198
3199       if (code == AND)
3200         {
3201           if (! rhs_andsi3_operand (XEXP (x, 1), SImode))
3202             *total += rtx_cost (XEXP (x, 1), code, speed);
3203         }
3204       else
3205         {
3206           if (! regorlog2_operand (XEXP (x, 1), SImode))
3207             *total += rtx_cost (XEXP (x, 1), code, speed);
3208         }
3209
3210       return true;
3211
3212     case ZERO_EXTRACT:
3213     case SIGN_EXTRACT:
3214       if (outer_code == SET
3215           && XEXP (x, 1) == const1_rtx
3216           && GET_CODE (XEXP (x, 2)) == CONST_INT)
3217         {
3218           *total = 2 * cost2;
3219           return true;
3220         }
3221       /* fall through */
3222
3223     case SIGN_EXTEND:
3224     case ZERO_EXTEND:
3225       *total = cost2;
3226       return true;
3227
3228     case MULT:
3229         {
3230           op0 = XEXP (x, 0);
3231           op1 = XEXP (x, 1);
3232           if (GET_CODE (op0) == GET_CODE (op1)
3233               && (GET_CODE (op0) == ZERO_EXTEND
3234                   || GET_CODE (op0) == SIGN_EXTEND))
3235             {
3236               *total = COSTS_N_INSNS (1);
3237               op0 = XEXP (op0, 0);
3238               op1 = XEXP (op1, 0);
3239             }
3240           else if (!speed)
3241             *total = COSTS_N_INSNS (1);
3242           else
3243             *total = COSTS_N_INSNS (3);
3244
3245           if (GET_CODE (op0) != REG
3246               && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
3247             *total += rtx_cost (op0, MULT, speed);
3248           if (GET_CODE (op1) != REG
3249               && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
3250             *total += rtx_cost (op1, MULT, speed);
3251         }
3252       return true;
3253
3254     case UDIV:
3255     case UMOD:
3256       *total = COSTS_N_INSNS (32);
3257       return true;
3258
3259     case VEC_CONCAT:
3260     case VEC_SELECT:
3261       if (outer_code == SET)
3262         *total = cost2;
3263       return true;
3264
3265     default:
3266       return false;
3267     }
3268 }
3269 \f
3270 /* Used for communication between {push,pop}_multiple_operation (which
3271    we use not only as a predicate) and the corresponding output functions.  */
3272 static int first_preg_to_save, first_dreg_to_save;
3273 static int n_regs_to_save;
3274
3275 int
3276 push_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3277 {
3278   int lastdreg = 8, lastpreg = 6;
3279   int i, group;
3280
3281   first_preg_to_save = lastpreg;
3282   first_dreg_to_save = lastdreg;
3283   for (i = 1, group = 0; i < XVECLEN (op, 0) - 1; i++)
3284     {
3285       rtx t = XVECEXP (op, 0, i);
3286       rtx src, dest;
3287       int regno;
3288
3289       if (GET_CODE (t) != SET)
3290         return 0;
3291
3292       src = SET_SRC (t);
3293       dest = SET_DEST (t);
3294       if (GET_CODE (dest) != MEM || ! REG_P (src))
3295         return 0;
3296       dest = XEXP (dest, 0);
3297       if (GET_CODE (dest) != PLUS
3298           || ! REG_P (XEXP (dest, 0))
3299           || REGNO (XEXP (dest, 0)) != REG_SP
3300           || GET_CODE (XEXP (dest, 1)) != CONST_INT
3301           || INTVAL (XEXP (dest, 1)) != -i * 4)
3302         return 0;
3303
3304       regno = REGNO (src);
3305       if (group == 0)
3306         {
3307           if (D_REGNO_P (regno))
3308             {
3309               group = 1;
3310               first_dreg_to_save = lastdreg = regno - REG_R0;
3311             }
3312           else if (regno >= REG_P0 && regno <= REG_P7)
3313             {
3314               group = 2;
3315               first_preg_to_save = lastpreg = regno - REG_P0;
3316             }
3317           else
3318             return 0;
3319
3320           continue;
3321         }
3322
3323       if (group == 1)
3324         {
3325           if (regno >= REG_P0 && regno <= REG_P7)
3326             {
3327               group = 2;
3328               first_preg_to_save = lastpreg = regno - REG_P0;
3329             }
3330           else if (regno != REG_R0 + lastdreg + 1)
3331             return 0;
3332           else
3333             lastdreg++;
3334         }
3335       else if (group == 2)
3336         {
3337           if (regno != REG_P0 + lastpreg + 1)
3338             return 0;
3339           lastpreg++;
3340         }
3341     }
3342   n_regs_to_save = 8 - first_dreg_to_save + 6 - first_preg_to_save;
3343   return 1;
3344 }
3345
3346 int
3347 pop_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
3348 {
3349   int lastdreg = 8, lastpreg = 6;
3350   int i, group;
3351
3352   for (i = 1, group = 0; i < XVECLEN (op, 0); i++)
3353     {
3354       rtx t = XVECEXP (op, 0, i);
3355       rtx src, dest;
3356       int regno;
3357
3358       if (GET_CODE (t) != SET)
3359         return 0;
3360
3361       src = SET_SRC (t);
3362       dest = SET_DEST (t);
3363       if (GET_CODE (src) != MEM || ! REG_P (dest))
3364         return 0;
3365       src = XEXP (src, 0);
3366
3367       if (i == 1)
3368         {
3369           if (! REG_P (src) || REGNO (src) != REG_SP)
3370             return 0;
3371         }
3372       else if (GET_CODE (src) != PLUS
3373                || ! REG_P (XEXP (src, 0))
3374                || REGNO (XEXP (src, 0)) != REG_SP
3375                || GET_CODE (XEXP (src, 1)) != CONST_INT
3376                || INTVAL (XEXP (src, 1)) != (i - 1) * 4)
3377         return 0;
3378
3379       regno = REGNO (dest);
3380       if (group == 0)
3381         {
3382           if (regno == REG_R7)
3383             {
3384               group = 1;
3385               lastdreg = 7;
3386             }
3387           else if (regno != REG_P0 + lastpreg - 1)
3388             return 0;
3389           else
3390             lastpreg--;
3391         }
3392       else if (group == 1)
3393         {
3394           if (regno != REG_R0 + lastdreg - 1)
3395             return 0;
3396           else
3397             lastdreg--;
3398         }
3399     }
3400   first_dreg_to_save = lastdreg;
3401   first_preg_to_save = lastpreg;
3402   n_regs_to_save = 8 - first_dreg_to_save + 6 - first_preg_to_save;
3403   return 1;
3404 }
3405
3406 /* Emit assembly code for one multi-register push described by INSN, with
3407    operands in OPERANDS.  */
3408
3409 void
3410 output_push_multiple (rtx insn, rtx *operands)
3411 {
3412   char buf[80];
3413   int ok;
3414   
3415   /* Validate the insn again, and compute first_[dp]reg_to_save. */
3416   ok = push_multiple_operation (PATTERN (insn), VOIDmode);
3417   gcc_assert (ok);
3418   
3419   if (first_dreg_to_save == 8)
3420     sprintf (buf, "[--sp] = ( p5:%d );\n", first_preg_to_save);
3421   else if (first_preg_to_save == 6)
3422     sprintf (buf, "[--sp] = ( r7:%d );\n", first_dreg_to_save);
3423   else
3424     sprintf (buf, "[--sp] = ( r7:%d, p5:%d );\n",
3425              first_dreg_to_save, first_preg_to_save);
3426
3427   output_asm_insn (buf, operands);
3428 }
3429
3430 /* Emit assembly code for one multi-register pop described by INSN, with
3431    operands in OPERANDS.  */
3432
3433 void
3434 output_pop_multiple (rtx insn, rtx *operands)
3435 {
3436   char buf[80];
3437   int ok;
3438   
3439   /* Validate the insn again, and compute first_[dp]reg_to_save. */
3440   ok = pop_multiple_operation (PATTERN (insn), VOIDmode);
3441   gcc_assert (ok);
3442
3443   if (first_dreg_to_save == 8)
3444     sprintf (buf, "( p5:%d ) = [sp++];\n", first_preg_to_save);
3445   else if (first_preg_to_save == 6)
3446     sprintf (buf, "( r7:%d ) = [sp++];\n", first_dreg_to_save);
3447   else
3448     sprintf (buf, "( r7:%d, p5:%d ) = [sp++];\n",
3449              first_dreg_to_save, first_preg_to_save);
3450
3451   output_asm_insn (buf, operands);
3452 }
3453
3454 /* Adjust DST and SRC by OFFSET bytes, and generate one move in mode MODE.  */
3455
3456 static void
3457 single_move_for_movmem (rtx dst, rtx src, enum machine_mode mode, HOST_WIDE_INT offset)
3458 {
3459   rtx scratch = gen_reg_rtx (mode);
3460   rtx srcmem, dstmem;
3461
3462   srcmem = adjust_address_nv (src, mode, offset);
3463   dstmem = adjust_address_nv (dst, mode, offset);
3464   emit_move_insn (scratch, srcmem);
3465   emit_move_insn (dstmem, scratch);
3466 }
3467
3468 /* Expand a string move operation of COUNT_EXP bytes from SRC to DST, with
3469    alignment ALIGN_EXP.  Return true if successful, false if we should fall
3470    back on a different method.  */
3471
3472 bool
3473 bfin_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp)
3474 {
3475   rtx srcreg, destreg, countreg;
3476   HOST_WIDE_INT align = 0;
3477   unsigned HOST_WIDE_INT count = 0;
3478
3479   if (GET_CODE (align_exp) == CONST_INT)
3480     align = INTVAL (align_exp);
3481   if (GET_CODE (count_exp) == CONST_INT)
3482     {
3483       count = INTVAL (count_exp);
3484 #if 0
3485       if (!TARGET_INLINE_ALL_STRINGOPS && count > 64)
3486         return false;
3487 #endif
3488     }
3489
3490   /* If optimizing for size, only do single copies inline.  */
3491   if (optimize_size)
3492     {
3493       if (count == 2 && align < 2)
3494         return false;
3495       if (count == 4 && align < 4)
3496         return false;
3497       if (count != 1 && count != 2 && count != 4)
3498         return false;
3499     }
3500   if (align < 2 && count != 1)
3501     return false;
3502
3503   destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
3504   if (destreg != XEXP (dst, 0))
3505     dst = replace_equiv_address_nv (dst, destreg);
3506   srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
3507   if (srcreg != XEXP (src, 0))
3508     src = replace_equiv_address_nv (src, srcreg);
3509
3510   if (count != 0 && align >= 2)
3511     {