OSDN Git Service

* flags.h (g_switch_value, g_switch_set): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / config / lm32 / lm32.c
1 /* Subroutines used for code generation on the Lattice Mico32 architecture.
2    Contributed by Jon Beniston <jon@beniston.com>
3
4    Copyright (C) 2009, 2010 Free Software Foundation, Inc.
5
6    This file is part of GCC.
7
8    GCC is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published
10    by the Free Software Foundation; either version 3, or (at your
11    option) any later version.
12
13    GCC is distributed in the hope that it will be useful, but WITHOUT
14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16    License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
33 #include "insn-attr.h"
34 #include "insn-codes.h"
35 #include "recog.h"
36 #include "output.h"
37 #include "tree.h"
38 #include "expr.h"
39 #include "flags.h"
40 #include "reload.h"
41 #include "tm_p.h"
42 #include "function.h"
43 #include "diagnostic-core.h"
44 #include "toplev.h"
45 #include "optabs.h"
46 #include "libfuncs.h"
47 #include "ggc.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "langhooks.h"
51 #include "tm-constrs.h"
52 #include "df.h"
53
54 struct lm32_frame_info
55 {
56   HOST_WIDE_INT total_size;     /* number of bytes of entire frame.  */
57   HOST_WIDE_INT callee_size;    /* number of bytes to save callee saves.  */
58   HOST_WIDE_INT pretend_size;   /* number of bytes we pretend caller did.  */
59   HOST_WIDE_INT args_size;      /* number of bytes for outgoing arguments.  */
60   HOST_WIDE_INT locals_size;    /* number of bytes for local variables.  */
61   unsigned int reg_save_mask;   /* mask of saved registers.  */
62 };
63
64 /* Prototypes for static functions.  */
65 static rtx emit_add (rtx dest, rtx src0, rtx src1);
66 static void expand_save_restore (struct lm32_frame_info *info, int op);
67 static void stack_adjust (HOST_WIDE_INT amount);
68 static bool lm32_in_small_data_p (const_tree);
69 static void lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum,
70                                          enum machine_mode mode, tree type,
71                                          int *pretend_size, int no_rtl);
72 static bool lm32_rtx_costs (rtx x, int code, int outer_code, int *total,
73                             bool speed);
74 static bool lm32_can_eliminate (const int, const int);
75 static bool
76 lm32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict);
77 static HOST_WIDE_INT lm32_compute_frame_size (int size);
78 static void lm32_option_override (void);
79
80 #undef TARGET_OPTION_OVERRIDE
81 #define TARGET_OPTION_OVERRIDE lm32_option_override
82 #undef TARGET_ADDRESS_COST
83 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
84 #undef TARGET_RTX_COSTS
85 #define TARGET_RTX_COSTS lm32_rtx_costs
86 #undef TARGET_IN_SMALL_DATA_P
87 #define TARGET_IN_SMALL_DATA_P lm32_in_small_data_p
88 #undef TARGET_PROMOTE_FUNCTION_MODE
89 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
90 #undef TARGET_SETUP_INCOMING_VARARGS
91 #define TARGET_SETUP_INCOMING_VARARGS lm32_setup_incoming_varargs
92 #undef TARGET_PROMOTE_PROTOTYPES
93 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
94 #undef TARGET_MIN_ANCHOR_OFFSET
95 #define TARGET_MIN_ANCHOR_OFFSET -0x8000
96 #undef TARGET_MAX_ANCHOR_OFFSET
97 #define TARGET_MAX_ANCHOR_OFFSET 0x7fff
98 #undef TARGET_CAN_ELIMINATE
99 #define TARGET_CAN_ELIMINATE lm32_can_eliminate
100 #undef TARGET_LEGITIMATE_ADDRESS_P
101 #define TARGET_LEGITIMATE_ADDRESS_P lm32_legitimate_address_p
102
103 struct gcc_target targetm = TARGET_INITIALIZER;
104
105 /* Current frame information calculated by lm32_compute_frame_size.  */
106 static struct lm32_frame_info current_frame_info;
107
108 /* Return non-zero if the given return type should be returned in memory.  */
109
110 int
111 lm32_return_in_memory (tree type)
112 {
113   HOST_WIDE_INT size;
114
115   if (!AGGREGATE_TYPE_P (type))
116     {
117       /* All simple types are returned in registers.  */
118       return 0;
119     }
120
121   size = int_size_in_bytes (type);
122   if (size >= 0 && size <= UNITS_PER_WORD)
123     {
124       /* If it can fit in one register.  */
125       return 0;
126     }
127
128   return 1;
129 }
130
131 /* Generate an emit a word sized add instruction.  */
132
133 static rtx
134 emit_add (rtx dest, rtx src0, rtx src1)
135 {
136   rtx insn;
137   insn = emit_insn (gen_addsi3 (dest, src0, src1));
138   return insn;
139 }
140
141 /* Generate the code to compare (and possibly branch) two integer values
142    TEST_CODE is the comparison code we are trying to emulate 
143      (or implement directly)
144    RESULT is where to store the result of the comparison, 
145      or null to emit a branch
146    CMP0 CMP1 are the two comparison operands
147    DESTINATION is the destination of the branch, or null to only compare
148    */
149
150 static void
151 gen_int_relational (enum rtx_code code, 
152                     rtx result, 
153                     rtx cmp0,   
154                     rtx cmp1,   
155                     rtx destination)    
156 {
157   enum machine_mode mode;
158   int branch_p;
159
160   mode = GET_MODE (cmp0);
161   if (mode == VOIDmode)
162     mode = GET_MODE (cmp1);
163
164   /* Is this a branch or compare.  */
165   branch_p = (destination != 0);
166
167   /* Instruction set doesn't support LE or LT, so swap operands and use 
168      GE, GT.  */
169   switch (code)
170     {
171     case LE:
172     case LT:
173     case LEU:
174     case LTU:
175       code = swap_condition (code);
176       rtx temp = cmp0;
177       cmp0 = cmp1;
178       cmp1 = temp;
179       break;
180     default:
181       break;
182     }
183
184   if (branch_p)
185     {
186       rtx insn;
187
188       /* Operands must be in registers.  */
189       if (!register_operand (cmp0, mode))
190         cmp0 = force_reg (mode, cmp0);
191       if (!register_operand (cmp1, mode))
192         cmp1 = force_reg (mode, cmp1);
193
194       /* Generate conditional branch instruction.  */
195       rtx cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
196       rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
197       insn = gen_rtx_SET (VOIDmode, pc_rtx,
198                           gen_rtx_IF_THEN_ELSE (VOIDmode,
199                                                 cond, label, pc_rtx));
200       emit_jump_insn (insn);
201     }
202   else
203     {
204       /* We can't have const_ints in cmp0, other than 0.  */
205       if ((GET_CODE (cmp0) == CONST_INT) && (INTVAL (cmp0) != 0))
206         cmp0 = force_reg (mode, cmp0);
207
208       /* If the comparison is against an int not in legal range
209          move it into a register.  */
210       if (GET_CODE (cmp1) == CONST_INT)
211         {
212           switch (code)
213             {
214             case EQ:
215             case NE:
216             case LE:
217             case LT:
218             case GE:
219             case GT:
220               if (!satisfies_constraint_K (cmp1))
221                 cmp1 = force_reg (mode, cmp1);
222               break;
223             case LEU:
224             case LTU:
225             case GEU:
226             case GTU:
227               if (!satisfies_constraint_L (cmp1))
228                 cmp1 = force_reg (mode, cmp1);
229               break;
230             default:
231               gcc_unreachable ();
232             }
233         }
234
235       /* Generate compare instruction.  */
236       emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1));
237     }
238 }
239
240 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
241    and OPERAND[3].  Store the result in OPERANDS[0].  */
242
243 void
244 lm32_expand_scc (rtx operands[])
245 {
246   rtx target = operands[0];
247   enum rtx_code code = GET_CODE (operands[1]);
248   rtx op0 = operands[2];
249   rtx op1 = operands[3];
250
251   gen_int_relational (code, target, op0, op1, NULL_RTX);  
252 }
253
254 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
255    CODE and jump to OPERANDS[3] if the condition holds.  */
256
257 void
258 lm32_expand_conditional_branch (rtx operands[])
259 {
260   enum rtx_code code = GET_CODE (operands[0]);
261   rtx op0 = operands[1];
262   rtx op1 = operands[2];
263   rtx destination = operands[3];
264
265   gen_int_relational (code, NULL_RTX, op0, op1, destination);  
266 }
267
268 /* Generate and emit RTL to save or restore callee save registers.  */
269 static void
270 expand_save_restore (struct lm32_frame_info *info, int op)
271 {
272   unsigned int reg_save_mask = info->reg_save_mask;
273   int regno;
274   HOST_WIDE_INT offset;
275   rtx insn;
276
277   /* Callee saves are below locals and above outgoing arguments.  */
278   offset = info->args_size + info->callee_size;
279   for (regno = 0; regno <= 31; regno++)
280     {
281       if ((reg_save_mask & (1 << regno)) != 0)
282         {
283           rtx offset_rtx;
284           rtx mem;
285           
286           offset_rtx = GEN_INT (offset);
287           if (satisfies_constraint_K (offset_rtx))
288             {   
289               mem = gen_rtx_MEM (word_mode,
290                                  gen_rtx_PLUS (Pmode,
291                                                stack_pointer_rtx,
292                                                offset_rtx));
293             }
294           else
295             {
296               /* r10 is caller saved so it can be used as a temp reg.  */
297               rtx r10;        
298                
299               r10 = gen_rtx_REG (word_mode, 10);
300               insn = emit_move_insn (r10, offset_rtx);
301               if (op == 0)
302                 RTX_FRAME_RELATED_P (insn) = 1;
303               insn = emit_add (r10, r10, stack_pointer_rtx);
304               if (op == 0)
305                 RTX_FRAME_RELATED_P (insn) = 1;                
306               mem = gen_rtx_MEM (word_mode, r10);
307             }                                                       
308                     
309           if (op == 0)
310             insn = emit_move_insn (mem, gen_rtx_REG (word_mode, regno));
311           else
312             insn = emit_move_insn (gen_rtx_REG (word_mode, regno), mem);
313         
314           /* only prologue instructions which set the sp fp or save a
315              register should be marked as frame related.  */
316           if (op == 0)
317             RTX_FRAME_RELATED_P (insn) = 1;
318           offset -= UNITS_PER_WORD;
319         }
320     }
321 }
322
323 static void
324 stack_adjust (HOST_WIDE_INT amount)
325 {
326   rtx insn;
327
328   if (!IN_RANGE (amount, -32776, 32768))
329     {
330       /* r10 is caller saved so it can be used as a temp reg.  */
331       rtx r10;
332       r10 = gen_rtx_REG (word_mode, 10);
333       insn = emit_move_insn (r10, GEN_INT (amount));
334       if (amount < 0)
335         RTX_FRAME_RELATED_P (insn) = 1;
336       insn = emit_add (stack_pointer_rtx, stack_pointer_rtx, r10);
337       if (amount < 0)
338         RTX_FRAME_RELATED_P (insn) = 1;
339     }
340   else
341     {
342       insn = emit_add (stack_pointer_rtx,
343                        stack_pointer_rtx, GEN_INT (amount));
344       if (amount < 0)
345         RTX_FRAME_RELATED_P (insn) = 1;
346     }
347 }
348
349
350 /* Create and emit instructions for a functions prologue.  */
351 void
352 lm32_expand_prologue (void)
353 {
354   rtx insn;
355
356   lm32_compute_frame_size (get_frame_size ());
357
358   if (current_frame_info.total_size > 0)
359     {
360       /* Add space on stack new frame.  */
361       stack_adjust (-current_frame_info.total_size);
362
363       /* Save callee save registers.  */
364       if (current_frame_info.reg_save_mask != 0)
365         expand_save_restore (&current_frame_info, 0);
366
367       /* Setup frame pointer if it's needed.  */
368       if (frame_pointer_needed == 1)
369         {
370           /* Load offset - Don't use total_size, as that includes pretend_size, 
371              which isn't part of this frame?  */
372           insn =
373             emit_move_insn (frame_pointer_rtx,
374                             GEN_INT (current_frame_info.args_size +
375                                      current_frame_info.callee_size +
376                                      current_frame_info.locals_size));
377           RTX_FRAME_RELATED_P (insn) = 1;
378
379           /* Add in sp.  */
380           insn = emit_add (frame_pointer_rtx,
381                            frame_pointer_rtx, stack_pointer_rtx);
382           RTX_FRAME_RELATED_P (insn) = 1;
383         }
384
385       /* Prevent prologue from being scheduled into function body.  */
386       emit_insn (gen_blockage ());
387     }
388 }
389
390 /* Create an emit instructions for a functions epilogue.  */
391 void
392 lm32_expand_epilogue (void)
393 {
394   rtx ra_rtx = gen_rtx_REG (Pmode, RA_REGNUM);
395
396   lm32_compute_frame_size (get_frame_size ());
397
398   if (current_frame_info.total_size > 0)
399     {
400       /* Prevent stack code from being reordered.  */
401       emit_insn (gen_blockage ());
402
403       /* Restore callee save registers.  */
404       if (current_frame_info.reg_save_mask != 0)
405         expand_save_restore (&current_frame_info, 1);
406
407       /* Deallocate stack.  */
408       stack_adjust (current_frame_info.total_size);
409
410       /* Return to calling function.  */
411       emit_jump_insn (gen_return_internal (ra_rtx));
412     }
413   else
414     {
415       /* Return to calling function.  */
416       emit_jump_insn (gen_return_internal (ra_rtx));
417     }
418 }
419
420 /* Return the bytes needed to compute the frame pointer from the current
421    stack pointer.  */
422 static HOST_WIDE_INT
423 lm32_compute_frame_size (int size)
424 {
425   int regno;
426   HOST_WIDE_INT total_size, locals_size, args_size, pretend_size, callee_size;
427   unsigned int reg_save_mask;
428
429   locals_size = size;
430   args_size = crtl->outgoing_args_size;
431   pretend_size = crtl->args.pretend_args_size;
432   callee_size = 0;
433   reg_save_mask = 0;
434
435   /* Build mask that actually determines which regsiters we save
436      and calculate size required to store them in the stack.  */
437   for (regno = 1; regno < SP_REGNUM; regno++)
438     {
439       if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
440         {
441           reg_save_mask |= 1 << regno;
442           callee_size += UNITS_PER_WORD;
443         }
444     }
445   if (df_regs_ever_live_p (RA_REGNUM) || !current_function_is_leaf
446       || !optimize)
447     {
448       reg_save_mask |= 1 << RA_REGNUM;
449       callee_size += UNITS_PER_WORD;
450     }
451   if (!(reg_save_mask & (1 << FP_REGNUM)) && frame_pointer_needed)
452     {
453       reg_save_mask |= 1 << FP_REGNUM;
454       callee_size += UNITS_PER_WORD;
455     }
456
457   /* Compute total frame size.  */
458   total_size = pretend_size + args_size + locals_size + callee_size;
459
460   /* Align frame to appropriate boundary.  */
461   total_size = (total_size + 3) & ~3;
462
463   /* Save computed information.  */
464   current_frame_info.total_size = total_size;
465   current_frame_info.callee_size = callee_size;
466   current_frame_info.pretend_size = pretend_size;
467   current_frame_info.locals_size = locals_size;
468   current_frame_info.args_size = args_size;
469   current_frame_info.reg_save_mask = reg_save_mask;
470
471   return total_size;
472 }
473
474 void
475 lm32_print_operand (FILE * file, rtx op, int letter)
476 {
477   enum rtx_code code;
478
479   code = GET_CODE (op);
480
481   if (code == SIGN_EXTEND)
482     op = XEXP (op, 0), code = GET_CODE (op);
483   else if (code == REG || code == SUBREG)
484     {
485       int regnum;
486
487       if (code == REG)
488         regnum = REGNO (op);
489       else
490         regnum = true_regnum (op);
491
492       fprintf (file, "%s", reg_names[regnum]);
493     }
494   else if (code == HIGH)
495     output_addr_const (file, XEXP (op, 0));  
496   else if (code == MEM)
497     output_address (XEXP (op, 0));
498   else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
499     fprintf (file, "%s", reg_names[0]);
500   else if (GET_CODE (op) == CONST_DOUBLE)
501     {
502       if ((CONST_DOUBLE_LOW (op) != 0) || (CONST_DOUBLE_HIGH (op) != 0))
503         output_operand_lossage ("Only 0.0 can be loaded as an immediate");
504       else
505         fprintf (file, "0");
506     }
507   else if (code == EQ)
508     fprintf (file, "e  ");
509   else if (code == NE)
510     fprintf (file, "ne ");
511   else if (code == GT)
512     fprintf (file, "g  ");
513   else if (code == GTU)
514     fprintf (file, "gu ");
515   else if (code == LT)
516     fprintf (file, "l  ");
517   else if (code == LTU)
518     fprintf (file, "lu ");
519   else if (code == GE)
520     fprintf (file, "ge ");
521   else if (code == GEU)
522     fprintf (file, "geu");
523   else if (code == LE)
524     fprintf (file, "le ");
525   else if (code == LEU)
526     fprintf (file, "leu");
527   else
528     output_addr_const (file, op);
529 }
530
531 /* A C compound statement to output to stdio stream STREAM the
532    assembler syntax for an instruction operand that is a memory
533    reference whose address is ADDR.  ADDR is an RTL expression.
534
535    On some machines, the syntax for a symbolic address depends on
536    the section that the address refers to.  On these machines,
537    define the macro `ENCODE_SECTION_INFO' to store the information
538    into the `symbol_ref', and then check for it here.  */
539
540 void
541 lm32_print_operand_address (FILE * file, rtx addr)
542 {
543   switch (GET_CODE (addr))
544     {
545     case REG:
546       fprintf (file, "(%s+0)", reg_names[REGNO (addr)]);
547       break;
548
549     case MEM:
550       output_address (XEXP (addr, 0));
551       break;
552
553     case PLUS:
554       {
555         rtx arg0 = XEXP (addr, 0);
556         rtx arg1 = XEXP (addr, 1);
557
558         if (GET_CODE (arg0) == REG && CONSTANT_P (arg1))
559           {
560             if (GET_CODE (arg1) == CONST_INT)
561               fprintf (file, "(%s+%ld)", reg_names[REGNO (arg0)],
562                        INTVAL (arg1));
563             else
564               {
565                 fprintf (file, "(%s+", reg_names[REGNO (arg0)]);
566                 output_addr_const (file, arg1);
567                 fprintf (file, ")");
568               }
569           }
570         else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
571           output_addr_const (file, addr);
572         else
573           fatal_insn ("bad operand", addr);
574       }
575       break;
576
577     case SYMBOL_REF:
578       if (SYMBOL_REF_SMALL_P (addr))
579         {
580           fprintf (file, "gp(");
581           output_addr_const (file, addr);
582           fprintf (file, ")");
583         }
584       else
585         fatal_insn ("can't use non gp relative absolute address", addr);
586       break;
587
588     default:
589       fatal_insn ("invalid addressing mode", addr);
590       break;
591     }
592 }
593
594 /* Determine where to put an argument to a function.
595    Value is zero to push the argument on the stack,
596    or a hard register in which to store the argument.
597
598    MODE is the argument's machine mode.
599    TYPE is the data type of the argument (as a tree).
600     This is null for libcalls where that information may
601     not be available.
602    CUM is a variable of type CUMULATIVE_ARGS which gives info about
603     the preceding args and about the function being called.
604    NAMED is nonzero if this argument is a named parameter
605     (otherwise it is an extra parameter matching an ellipsis).  */
606
607 rtx
608 lm32_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
609                    tree type, int named)
610 {
611   if (mode == VOIDmode)
612     /* Compute operand 2 of the call insn.  */
613     return GEN_INT (0);
614
615   if (targetm.calls.must_pass_in_stack (mode, type))
616     return NULL_RTX;
617
618   if (!named || (cum + LM32_NUM_REGS2 (mode, type) > LM32_NUM_ARG_REGS))
619     return NULL_RTX;
620
621   return gen_rtx_REG (mode, cum + LM32_FIRST_ARG_REG);
622 }
623
624 HOST_WIDE_INT
625 lm32_compute_initial_elimination_offset (int from, int to)
626 {
627   HOST_WIDE_INT offset = 0;
628
629   switch (from)
630     {
631     case ARG_POINTER_REGNUM:
632       switch (to)
633         {
634         case FRAME_POINTER_REGNUM:
635           offset = 0;
636           break;
637         case STACK_POINTER_REGNUM:
638           offset =
639             lm32_compute_frame_size (get_frame_size ()) -
640             current_frame_info.pretend_size;
641           break;
642         default:
643           gcc_unreachable ();
644         }
645       break;
646     default:
647       gcc_unreachable ();
648     }
649
650   return offset;
651 }
652
653 static void
654 lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode,
655                              tree type, int *pretend_size, int no_rtl)
656 {
657   int first_anon_arg;
658   tree fntype;
659
660   fntype = TREE_TYPE (current_function_decl);
661
662   if (stdarg_p (fntype))
663     first_anon_arg = *cum + LM32_FIRST_ARG_REG;
664   else
665     {
666       /* this is the common case, we have been passed details setup
667          for the last named argument, we want to skip over the
668          registers, if any used in passing this named paramter in
669          order to determine which is the first registers used to pass
670          anonymous arguments.  */
671       int size;
672
673       if (mode == BLKmode)
674         size = int_size_in_bytes (type);
675       else
676         size = GET_MODE_SIZE (mode);
677
678       first_anon_arg =
679         *cum + LM32_FIRST_ARG_REG +
680         ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
681     }
682
683   if ((first_anon_arg < (LM32_FIRST_ARG_REG + LM32_NUM_ARG_REGS)) && !no_rtl)
684     {
685       int first_reg_offset = first_anon_arg;
686       int size = LM32_FIRST_ARG_REG + LM32_NUM_ARG_REGS - first_anon_arg;
687       rtx regblock;
688
689       regblock = gen_rtx_MEM (BLKmode,
690                               plus_constant (arg_pointer_rtx,
691                                              FIRST_PARM_OFFSET (0)));
692       move_block_from_reg (first_reg_offset, regblock, size);
693
694       *pretend_size = size * UNITS_PER_WORD;
695     }
696 }
697
698 /* Override command line options.  */
699 static void
700 lm32_option_override (void)
701 {
702   /* We must have sign-extend enabled if barrel-shift isn't.  */
703   if (!TARGET_BARREL_SHIFT_ENABLED && !TARGET_SIGN_EXTEND_ENABLED)
704     target_flags |= MASK_SIGN_EXTEND_ENABLED;
705 }
706
707 /* Return nonzero if this function is known to have a null epilogue.
708    This allows the optimizer to omit jumps to jumps if no stack
709    was created.  */
710 int
711 lm32_can_use_return (void)
712 {
713   if (!reload_completed)
714     return 0;
715
716   if (df_regs_ever_live_p (RA_REGNUM) || crtl->profile)
717     return 0;
718
719   if (lm32_compute_frame_size (get_frame_size ()) != 0)
720     return 0;
721
722   return 1;
723 }
724
725 /* Support function to determine the return address of the function
726    'count' frames back up the stack.  */
727 rtx
728 lm32_return_addr_rtx (int count, rtx frame)
729 {
730   rtx r;
731   if (count == 0)
732     {
733       if (!df_regs_ever_live_p (RA_REGNUM))
734         r = gen_rtx_REG (Pmode, RA_REGNUM);
735       else
736         {
737           r = gen_rtx_MEM (Pmode,
738                            gen_rtx_PLUS (Pmode, frame,
739                                          GEN_INT (-2 * UNITS_PER_WORD)));
740           set_mem_alias_set (r, get_frame_alias_set ());
741         }
742     }
743   else if (flag_omit_frame_pointer)
744     r = NULL_RTX;
745   else
746     {
747       r = gen_rtx_MEM (Pmode,
748                        gen_rtx_PLUS (Pmode, frame,
749                                      GEN_INT (-2 * UNITS_PER_WORD)));
750       set_mem_alias_set (r, get_frame_alias_set ());
751     }
752   return r;
753 }
754
755 /* Return true if EXP should be placed in the small data section.  */
756
757 static bool
758 lm32_in_small_data_p (const_tree exp)
759 {
760   /* We want to merge strings, so we never consider them small data.  */
761   if (TREE_CODE (exp) == STRING_CST)
762     return false;
763
764   /* Functions are never in the small data area.  Duh.  */
765   if (TREE_CODE (exp) == FUNCTION_DECL)
766     return false;
767
768   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
769     {
770       const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
771       if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0)
772         return true;
773     }
774   else
775     {
776       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
777
778       /* If this is an incomplete type with size 0, then we can't put it
779          in sdata because it might be too big when completed.  */
780       if (size > 0 && size <= g_switch_value)
781         return true;
782     }
783
784   return false;
785 }
786
787 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
788    Assume that the areas do not overlap.  */
789
790 static void
791 lm32_block_move_inline (rtx dest, rtx src, HOST_WIDE_INT length,
792                         HOST_WIDE_INT alignment)
793 {
794   HOST_WIDE_INT offset, delta;
795   unsigned HOST_WIDE_INT bits;
796   int i;
797   enum machine_mode mode;
798   rtx *regs;
799
800   /* Work out how many bits to move at a time.  */
801   switch (alignment)
802     {
803     case 1:
804       bits = 8;
805       break;
806     case 2:
807       bits = 16;
808       break;
809     default:
810       bits = 32;
811       break;
812     }
813
814   mode = mode_for_size (bits, MODE_INT, 0);
815   delta = bits / BITS_PER_UNIT;
816
817   /* Allocate a buffer for the temporary registers.  */
818   regs = alloca (sizeof (rtx) * length / delta);
819
820   /* Load as many BITS-sized chunks as possible.  */
821   for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
822     {
823       regs[i] = gen_reg_rtx (mode);
824       emit_move_insn (regs[i], adjust_address (src, mode, offset));
825     }
826
827   /* Copy the chunks to the destination.  */
828   for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
829     emit_move_insn (adjust_address (dest, mode, offset), regs[i]);
830
831   /* Mop up any left-over bytes.  */
832   if (offset < length)
833     {
834       src = adjust_address (src, BLKmode, offset);
835       dest = adjust_address (dest, BLKmode, offset);
836       move_by_pieces (dest, src, length - offset,
837                       MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), 0);
838     }
839 }
840
841 /* Expand string/block move operations.
842
843    operands[0] is the pointer to the destination.
844    operands[1] is the pointer to the source.
845    operands[2] is the number of bytes to move.
846    operands[3] is the alignment.  */
847
848 int
849 lm32_expand_block_move (rtx * operands)
850 {
851   if ((GET_CODE (operands[2]) == CONST_INT) && (INTVAL (operands[2]) <= 32))
852     {
853       lm32_block_move_inline (operands[0], operands[1], INTVAL (operands[2]),
854                               INTVAL (operands[3]));
855       return 1;
856     }
857   return 0;
858 }
859
860 /* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol
861    isn't protected by a PIC unspec.  */
862 int
863 nonpic_symbol_mentioned_p (rtx x)
864 {
865   const char *fmt;
866   int i;
867
868   if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF
869       || GET_CODE (x) == PC)
870     return 1;
871
872   /* We don't want to look into the possible MEM location of a
873      CONST_DOUBLE, since we're not going to use it, in general.  */
874   if (GET_CODE (x) == CONST_DOUBLE)
875     return 0;
876
877   if (GET_CODE (x) == UNSPEC)
878     return 0;
879
880   fmt = GET_RTX_FORMAT (GET_CODE (x));
881   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
882     {
883       if (fmt[i] == 'E')
884         {
885           int j;
886
887           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
888             if (nonpic_symbol_mentioned_p (XVECEXP (x, i, j)))
889               return 1;
890         }
891       else if (fmt[i] == 'e' && nonpic_symbol_mentioned_p (XEXP (x, i)))
892         return 1;
893     }
894
895   return 0;
896 }
897
898 /* Compute a (partial) cost for rtx X.  Return true if the complete
899    cost has been computed, and false if subexpressions should be
900    scanned.  In either case, *TOTAL contains the cost result.  */
901
902 static bool
903 lm32_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
904 {
905   enum machine_mode mode = GET_MODE (x);
906   bool small_mode;
907
908   const int arithmetic_latency = 1;
909   const int shift_latency = 1;
910   const int compare_latency = 2;
911   const int multiply_latency = 3;
912   const int load_latency = 3;
913   const int libcall_size_cost = 5;
914
915   /* Determine if we can handle the given mode size in a single instruction.  */
916   small_mode = (mode == QImode) || (mode == HImode) || (mode == SImode);
917
918   switch (code)
919     {
920
921     case PLUS:
922     case MINUS:
923     case AND:
924     case IOR:
925     case XOR:
926     case NOT:
927     case NEG:
928       if (!speed)
929         *total = COSTS_N_INSNS (LM32_NUM_REGS (mode));
930       else
931         *total =
932           COSTS_N_INSNS (arithmetic_latency + (LM32_NUM_REGS (mode) - 1));
933       break;
934
935     case COMPARE:
936       if (small_mode)
937         {
938           if (!speed)
939             *total = COSTS_N_INSNS (1);
940           else
941             *total = COSTS_N_INSNS (compare_latency);
942         }
943       else
944         {
945           /* FIXME. Guessing here.  */
946           *total = COSTS_N_INSNS (LM32_NUM_REGS (mode) * (2 + 3) / 2);
947         }
948       break;
949
950     case ASHIFT:
951     case ASHIFTRT:
952     case LSHIFTRT:
953       if (TARGET_BARREL_SHIFT_ENABLED && small_mode)
954         {
955           if (!speed)
956             *total = COSTS_N_INSNS (1);
957           else
958             *total = COSTS_N_INSNS (shift_latency);
959         }
960       else if (TARGET_BARREL_SHIFT_ENABLED)
961         {
962           /* FIXME: Guessing here.  */
963           *total = COSTS_N_INSNS (LM32_NUM_REGS (mode) * 4);
964         }
965       else if (small_mode && GET_CODE (XEXP (x, 1)) == CONST_INT)
966         {
967           *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
968         }
969       else
970         {
971           /* Libcall.  */
972           if (!speed)
973             *total = COSTS_N_INSNS (libcall_size_cost);
974           else
975             *total = COSTS_N_INSNS (100);
976         }
977       break;
978
979     case MULT:
980       if (TARGET_MULTIPLY_ENABLED && small_mode)
981         {
982           if (!speed)
983             *total = COSTS_N_INSNS (1);
984           else
985             *total = COSTS_N_INSNS (multiply_latency);
986         }
987       else
988         {
989           /* Libcall.  */
990           if (!speed)
991             *total = COSTS_N_INSNS (libcall_size_cost);
992           else
993             *total = COSTS_N_INSNS (100);
994         }
995       break;
996
997     case DIV:
998     case MOD:
999     case UDIV:
1000     case UMOD:
1001       if (TARGET_DIVIDE_ENABLED && small_mode)
1002         {
1003           if (!speed)
1004             *total = COSTS_N_INSNS (1);
1005           else
1006             {
1007               if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1008                 {
1009                   int cycles = 0;
1010                   unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
1011
1012                   while (i)
1013                     {
1014                       i >>= 2;
1015                       cycles++;
1016                     }
1017                   if (IN_RANGE (i, 0, 65536))
1018                     *total = COSTS_N_INSNS (1 + 1 + cycles);
1019                   else
1020                     *total = COSTS_N_INSNS (2 + 1 + cycles);
1021                   return true;
1022                 }
1023               else if (GET_CODE (XEXP (x, 1)) == REG)
1024                 {
1025                   *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode) / 2);
1026                   return true;
1027                 }
1028               else
1029                 {
1030                   *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode) / 2);
1031                   return false;
1032                 }
1033             }
1034         }
1035       else
1036         {
1037           /* Libcall.  */
1038           if (!speed)
1039             *total = COSTS_N_INSNS (libcall_size_cost);
1040           else
1041             *total = COSTS_N_INSNS (100);
1042         }
1043       break;
1044
1045     case HIGH:
1046     case LO_SUM:
1047       if (!speed)
1048         *total = COSTS_N_INSNS (1);
1049       else
1050         *total = COSTS_N_INSNS (arithmetic_latency);
1051       break;
1052
1053     case ZERO_EXTEND:
1054       if (MEM_P (XEXP (x, 0)))
1055         *total = COSTS_N_INSNS (0);
1056       else if (small_mode)
1057         {
1058           if (!speed)
1059             *total = COSTS_N_INSNS (1);
1060           else
1061             *total = COSTS_N_INSNS (arithmetic_latency);
1062         }
1063       else
1064         *total = COSTS_N_INSNS (LM32_NUM_REGS (mode) / 2);
1065       break;
1066
1067     case CONST_INT:
1068       {
1069         switch (outer_code)
1070           {
1071           case HIGH:
1072           case LO_SUM:
1073             *total = COSTS_N_INSNS (0);
1074             return true;
1075
1076           case AND:
1077           case XOR:
1078           case IOR:
1079           case ASHIFT:
1080           case ASHIFTRT:
1081           case LSHIFTRT:
1082           case ROTATE:
1083           case ROTATERT:
1084             if (satisfies_constraint_L (x))
1085               *total = COSTS_N_INSNS (0);
1086             else
1087               *total = COSTS_N_INSNS (2);
1088             return true;
1089
1090           case SET:
1091           case PLUS:
1092           case MINUS:
1093           case COMPARE:
1094             if (satisfies_constraint_K (x))
1095               *total = COSTS_N_INSNS (0);
1096             else
1097               *total = COSTS_N_INSNS (2);
1098             return true;
1099
1100           case MULT:
1101             if (TARGET_MULTIPLY_ENABLED)
1102               {
1103                 if (satisfies_constraint_K (x))
1104                  *total = COSTS_N_INSNS (0);
1105                 else
1106                   *total = COSTS_N_INSNS (2);
1107                 return true;
1108               }
1109             /* Fall through.  */ 
1110
1111           default:
1112             if (satisfies_constraint_K (x))
1113               *total = COSTS_N_INSNS (1);
1114             else
1115               *total = COSTS_N_INSNS (2);
1116             return true;
1117           }
1118       }
1119
1120     case SYMBOL_REF:
1121     case CONST:
1122       switch (outer_code)
1123         {
1124         case HIGH:
1125         case LO_SUM:
1126           *total = COSTS_N_INSNS (0);
1127           return true;
1128
1129         case MEM:
1130         case SET:
1131           if (g_switch_value)
1132             {
1133               *total = COSTS_N_INSNS (0);
1134               return true;
1135             }
1136           break;
1137         }
1138       /* Fall through.  */
1139
1140     case LABEL_REF:
1141     case CONST_DOUBLE:
1142       *total = COSTS_N_INSNS (2);
1143       return true;
1144
1145     case SET:
1146       *total = COSTS_N_INSNS (1);
1147       break;
1148
1149     case MEM:
1150       if (!speed)
1151         *total = COSTS_N_INSNS (1);
1152       else
1153         *total = COSTS_N_INSNS (load_latency);
1154       break;
1155
1156     }
1157
1158   return false;
1159 }
1160
1161 /* Implemenent TARGET_CAN_ELIMINATE.  */
1162
1163 bool
1164 lm32_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
1165 {
1166   return (to == STACK_POINTER_REGNUM && frame_pointer_needed) ? false : true;
1167 }
1168
1169 /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
1170
1171 static bool
1172 lm32_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict)
1173 {  
1174    /* (rM) */                                                    
1175   if (strict && REG_P (x) && STRICT_REG_OK_FOR_BASE_P (x))
1176     return true;
1177   if (!strict && REG_P (x) && NONSTRICT_REG_OK_FOR_BASE_P (x))
1178     return true;
1179        
1180   /* (rM)+literal) */                               
1181   if (GET_CODE (x) == PLUS  
1182      && REG_P (XEXP (x, 0))                                     
1183      && ((strict && STRICT_REG_OK_FOR_BASE_P (XEXP (x, 0)))
1184          || (!strict && NONSTRICT_REG_OK_FOR_BASE_P (XEXP (x, 0))))                           
1185      && GET_CODE (XEXP (x, 1)) == CONST_INT                      
1186      && satisfies_constraint_K (XEXP ((x), 1)))
1187     return true;
1188               
1189   /* gp(sym)  */   
1190   if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x)) 
1191     return true;
1192     
1193   return false;                                
1194 }
1195
1196 /* Check a move is not memory to memory.  */ 
1197
1198 bool 
1199 lm32_move_ok (enum machine_mode mode, rtx operands[2]) {
1200   if (memory_operand (operands[0], mode))
1201     return register_or_zero_operand (operands[1], mode);
1202   return true;
1203 }
1204
1205 /* Implement LEGITIMATE_CONSTANT_P.  */
1206
1207 bool
1208 lm32_legitimate_constant_p (rtx x)
1209 {
1210   /* 32-bit addresses require multiple instructions.  */  
1211   if (!flag_pic && reloc_operand (x, GET_MODE (x)))
1212     return false; 
1213   
1214   return true;
1215 }