OSDN Git Service

4288ed285d92648ede5e466ac1927f3c3260093f
[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 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 "toplev.h"
44 #include "optabs.h"
45 #include "libfuncs.h"
46 #include "ggc.h"
47 #include "target.h"
48 #include "target-def.h"
49 #include "langhooks.h"
50 #include "tm-constrs.h"
51 #include "df.h"
52
53 struct lm32_frame_info
54 {
55   HOST_WIDE_INT total_size;     /* number of bytes of entire frame.  */
56   HOST_WIDE_INT callee_size;    /* number of bytes to save callee saves.  */
57   HOST_WIDE_INT pretend_size;   /* number of bytes we pretend caller did.  */
58   HOST_WIDE_INT args_size;      /* number of bytes for outgoing arguments.  */
59   HOST_WIDE_INT locals_size;    /* number of bytes for local variables.  */
60   unsigned int reg_save_mask;   /* mask of saved registers.  */
61 };
62
63 /* Prototypes for static functions.  */
64 static rtx emit_add (rtx dest, rtx src0, rtx src1);
65 static void expand_save_restore (struct lm32_frame_info *info, int op);
66 static void stack_adjust (HOST_WIDE_INT amount);
67 static bool lm32_in_small_data_p (const_tree);
68 static void lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum,
69                                          enum machine_mode mode, tree type,
70                                          int *pretend_size, int no_rtl);
71 static bool lm32_rtx_costs (rtx x, int code, int outer_code, int *total,
72                             bool speed);
73 static bool lm32_can_eliminate (const int, const int);
74 static bool
75 lm32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict);
76 static HOST_WIDE_INT lm32_compute_frame_size (int size);
77
78 #undef TARGET_ADDRESS_COST
79 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
80 #undef TARGET_RTX_COSTS
81 #define TARGET_RTX_COSTS lm32_rtx_costs
82 #undef TARGET_IN_SMALL_DATA_P
83 #define TARGET_IN_SMALL_DATA_P lm32_in_small_data_p
84 #undef TARGET_PROMOTE_FUNCTION_MODE
85 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
86 #undef TARGET_SETUP_INCOMING_VARARGS
87 #define TARGET_SETUP_INCOMING_VARARGS lm32_setup_incoming_varargs
88 #undef TARGET_PROMOTE_PROTOTYPES
89 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
90 #undef TARGET_MIN_ANCHOR_OFFSET
91 #define TARGET_MIN_ANCHOR_OFFSET -0x8000
92 #undef TARGET_MAX_ANCHOR_OFFSET
93 #define TARGET_MAX_ANCHOR_OFFSET 0x7fff
94 #undef TARGET_CAN_ELIMINATE
95 #define TARGET_CAN_ELIMINATE lm32_can_eliminate
96 #undef TARGET_LEGITIMATE_ADDRESS_P
97 #define TARGET_LEGITIMATE_ADDRESS_P lm32_legitimate_address_p
98
99 struct gcc_target targetm = TARGET_INITIALIZER;
100
101 /* Current frame information calculated by lm32_compute_frame_size.  */
102 static struct lm32_frame_info current_frame_info;
103
104 /* Return non-zero if the given return type should be returned in memory.  */
105
106 int
107 lm32_return_in_memory (tree type)
108 {
109   HOST_WIDE_INT size;
110
111   if (!AGGREGATE_TYPE_P (type))
112     {
113       /* All simple types are returned in registers.  */
114       return 0;
115     }
116
117   size = int_size_in_bytes (type);
118   if (size >= 0 && size <= UNITS_PER_WORD)
119     {
120       /* If it can fit in one register.  */
121       return 0;
122     }
123
124   return 1;
125 }
126
127 /* Generate an emit a word sized add instruction.  */
128
129 static rtx
130 emit_add (rtx dest, rtx src0, rtx src1)
131 {
132   rtx insn;
133   insn = emit_insn (gen_addsi3 (dest, src0, src1));
134   return insn;
135 }
136
137 /* Generate the code to compare (and possibly branch) two integer values
138    TEST_CODE is the comparison code we are trying to emulate 
139      (or implement directly)
140    RESULT is where to store the result of the comparison, 
141      or null to emit a branch
142    CMP0 CMP1 are the two comparison operands
143    DESTINATION is the destination of the branch, or null to only compare
144    */
145
146 static void
147 gen_int_relational (enum rtx_code code, 
148                     rtx result, 
149                     rtx cmp0,   
150                     rtx cmp1,   
151                     rtx destination)    
152 {
153   enum machine_mode mode;
154   int branch_p;
155
156   mode = GET_MODE (cmp0);
157   if (mode == VOIDmode)
158     mode = GET_MODE (cmp1);
159
160   /* Is this a branch or compare.  */
161   branch_p = (destination != 0);
162
163   /* Instruction set doesn't support LE or LT, so swap operands and use 
164      GE, GT.  */
165   switch (code)
166     {
167     case LE:
168     case LT:
169     case LEU:
170     case LTU:
171       code = swap_condition (code);
172       rtx temp = cmp0;
173       cmp0 = cmp1;
174       cmp1 = temp;
175       break;
176     default:
177       break;
178     }
179
180   if (branch_p)
181     {
182       rtx insn;
183
184       /* Operands must be in registers.  */
185       if (!register_operand (cmp0, mode))
186         cmp0 = force_reg (mode, cmp0);
187       if (!register_operand (cmp1, mode))
188         cmp1 = force_reg (mode, cmp1);
189
190       /* Generate conditional branch instruction.  */
191       rtx cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
192       rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
193       insn = gen_rtx_SET (VOIDmode, pc_rtx,
194                           gen_rtx_IF_THEN_ELSE (VOIDmode,
195                                                 cond, label, pc_rtx));
196       emit_jump_insn (insn);
197     }
198   else
199     {
200       /* We can't have const_ints in cmp0, other than 0.  */
201       if ((GET_CODE (cmp0) == CONST_INT) && (INTVAL (cmp0) != 0))
202         cmp0 = force_reg (mode, cmp0);
203
204       /* If the comparison is against an int not in legal range
205          move it into a register.  */
206       if (GET_CODE (cmp1) == CONST_INT)
207         {
208           switch (code)
209             {
210             case EQ:
211             case NE:
212             case LE:
213             case LT:
214             case GE:
215             case GT:
216               if (!satisfies_constraint_K (cmp1))
217                 cmp1 = force_reg (mode, cmp1);
218               break;
219             case LEU:
220             case LTU:
221             case GEU:
222             case GTU:
223               if (!satisfies_constraint_L (cmp1))
224                 cmp1 = force_reg (mode, cmp1);
225               break;
226             default:
227               gcc_unreachable ();
228             }
229         }
230
231       /* Generate compare instruction.  */
232       emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1));
233     }
234 }
235
236 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
237    and OPERAND[3].  Store the result in OPERANDS[0].  */
238
239 void
240 lm32_expand_scc (rtx operands[])
241 {
242   rtx target = operands[0];
243   enum rtx_code code = GET_CODE (operands[1]);
244   rtx op0 = operands[2];
245   rtx op1 = operands[3];
246
247   gen_int_relational (code, target, op0, op1, NULL_RTX);  
248 }
249
250 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
251    CODE and jump to OPERANDS[3] if the condition holds.  */
252
253 void
254 lm32_expand_conditional_branch (rtx operands[])
255 {
256   enum rtx_code code = GET_CODE (operands[0]);
257   rtx op0 = operands[1];
258   rtx op1 = operands[2];
259   rtx destination = operands[3];
260
261   gen_int_relational (code, NULL_RTX, op0, op1, destination);  
262 }
263
264 /* Generate and emit RTL to save or restore callee save registers.  */
265 static void
266 expand_save_restore (struct lm32_frame_info *info, int op)
267 {
268   unsigned int reg_save_mask = info->reg_save_mask;
269   int regno;
270   HOST_WIDE_INT offset;
271   rtx insn;
272
273   /* Callee saves are below locals and above outgoing arguments.  */
274   offset = info->args_size + info->callee_size;
275   for (regno = 0; regno <= 31; regno++)
276     {
277       if ((reg_save_mask & (1 << regno)) != 0)
278         {
279           rtx offset_rtx;
280           rtx mem;
281           
282           offset_rtx = GEN_INT (offset);
283           if (satisfies_constraint_K (offset_rtx))
284             {   
285               mem = gen_rtx_MEM (word_mode,
286                                  gen_rtx_PLUS (Pmode,
287                                                stack_pointer_rtx,
288                                                offset_rtx));
289             }
290           else
291             {
292               /* r10 is caller saved so it can be used as a temp reg.  */
293               rtx r10;        
294                
295               r10 = gen_rtx_REG (word_mode, 10);
296               insn = emit_move_insn (r10, offset_rtx);
297               if (op == 0)
298                 RTX_FRAME_RELATED_P (insn) = 1;
299               insn = emit_add (r10, r10, stack_pointer_rtx);
300               if (op == 0)
301                 RTX_FRAME_RELATED_P (insn) = 1;                
302               mem = gen_rtx_MEM (word_mode, r10);
303             }                                                       
304                     
305           if (op == 0)
306             insn = emit_move_insn (mem, gen_rtx_REG (word_mode, regno));
307           else
308             insn = emit_move_insn (gen_rtx_REG (word_mode, regno), mem);
309         
310           /* only prologue instructions which set the sp fp or save a
311              register should be marked as frame related.  */
312           if (op == 0)
313             RTX_FRAME_RELATED_P (insn) = 1;
314           offset -= UNITS_PER_WORD;
315         }
316     }
317 }
318
319 static void
320 stack_adjust (HOST_WIDE_INT amount)
321 {
322   rtx insn;
323
324   if (!IN_RANGE (amount, -32776, 32768))
325     {
326       /* r10 is caller saved so it can be used as a temp reg.  */
327       rtx r10;
328       r10 = gen_rtx_REG (word_mode, 10);
329       insn = emit_move_insn (r10, GEN_INT (amount));
330       if (amount < 0)
331         RTX_FRAME_RELATED_P (insn) = 1;
332       insn = emit_add (stack_pointer_rtx, stack_pointer_rtx, r10);
333       if (amount < 0)
334         RTX_FRAME_RELATED_P (insn) = 1;
335     }
336   else
337     {
338       insn = emit_add (stack_pointer_rtx,
339                        stack_pointer_rtx, GEN_INT (amount));
340       if (amount < 0)
341         RTX_FRAME_RELATED_P (insn) = 1;
342     }
343 }
344
345
346 /* Create and emit instructions for a functions prologue.  */
347 void
348 lm32_expand_prologue (void)
349 {
350   rtx insn;
351
352   lm32_compute_frame_size (get_frame_size ());
353
354   if (current_frame_info.total_size > 0)
355     {
356       /* Add space on stack new frame.  */
357       stack_adjust (-current_frame_info.total_size);
358
359       /* Save callee save registers.  */
360       if (current_frame_info.reg_save_mask != 0)
361         expand_save_restore (&current_frame_info, 0);
362
363       /* Setup frame pointer if it's needed.  */
364       if (frame_pointer_needed == 1)
365         {
366           /* Load offset - Don't use total_size, as that includes pretend_size, 
367              which isn't part of this frame?  */
368           insn =
369             emit_move_insn (frame_pointer_rtx,
370                             GEN_INT (current_frame_info.args_size +
371                                      current_frame_info.callee_size +
372                                      current_frame_info.locals_size));
373           RTX_FRAME_RELATED_P (insn) = 1;
374
375           /* Add in sp.  */
376           insn = emit_add (frame_pointer_rtx,
377                            frame_pointer_rtx, stack_pointer_rtx);
378           RTX_FRAME_RELATED_P (insn) = 1;
379         }
380
381       /* Prevent prologue from being scheduled into function body.  */
382       emit_insn (gen_blockage ());
383     }
384 }
385
386 /* Create an emit instructions for a functions epilogue.  */
387 void
388 lm32_expand_epilogue (void)
389 {
390   rtx ra_rtx = gen_rtx_REG (Pmode, RA_REGNUM);
391
392   lm32_compute_frame_size (get_frame_size ());
393
394   if (current_frame_info.total_size > 0)
395     {
396       /* Prevent stack code from being reordered.  */
397       emit_insn (gen_blockage ());
398
399       /* Restore callee save registers.  */
400       if (current_frame_info.reg_save_mask != 0)
401         expand_save_restore (&current_frame_info, 1);
402
403       /* Deallocate stack.  */
404       stack_adjust (current_frame_info.total_size);
405
406       /* Return to calling function.  */
407       emit_jump_insn (gen_return_internal (ra_rtx));
408     }
409   else
410     {
411       /* Return to calling function.  */
412       emit_jump_insn (gen_return_internal (ra_rtx));
413     }
414 }
415
416 /* Return the bytes needed to compute the frame pointer from the current
417    stack pointer.  */
418 static HOST_WIDE_INT
419 lm32_compute_frame_size (int size)
420 {
421   int regno;
422   HOST_WIDE_INT total_size, locals_size, args_size, pretend_size, callee_size;
423   unsigned int reg_save_mask;
424
425   locals_size = size;
426   args_size = crtl->outgoing_args_size;
427   pretend_size = crtl->args.pretend_args_size;
428   callee_size = 0;
429   reg_save_mask = 0;
430
431   /* Build mask that actually determines which regsiters we save
432      and calculate size required to store them in the stack.  */
433   for (regno = 1; regno < SP_REGNUM; regno++)
434     {
435       if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
436         {
437           reg_save_mask |= 1 << regno;
438           callee_size += UNITS_PER_WORD;
439         }
440     }
441   if (df_regs_ever_live_p (RA_REGNUM) || !current_function_is_leaf
442       || !optimize)
443     {
444       reg_save_mask |= 1 << RA_REGNUM;
445       callee_size += UNITS_PER_WORD;
446     }
447   if (!(reg_save_mask & (1 << FP_REGNUM)) && frame_pointer_needed)
448     {
449       reg_save_mask |= 1 << FP_REGNUM;
450       callee_size += UNITS_PER_WORD;
451     }
452
453   /* Compute total frame size.  */
454   total_size = pretend_size + args_size + locals_size + callee_size;
455
456   /* Align frame to appropriate boundary.  */
457   total_size = (total_size + 3) & ~3;
458
459   /* Save computed information.  */
460   current_frame_info.total_size = total_size;
461   current_frame_info.callee_size = callee_size;
462   current_frame_info.pretend_size = pretend_size;
463   current_frame_info.locals_size = locals_size;
464   current_frame_info.args_size = args_size;
465   current_frame_info.reg_save_mask = reg_save_mask;
466
467   return total_size;
468 }
469
470 void
471 lm32_print_operand (FILE * file, rtx op, int letter)
472 {
473   enum rtx_code code;
474
475   code = GET_CODE (op);
476
477   if (code == SIGN_EXTEND)
478     op = XEXP (op, 0), code = GET_CODE (op);
479   else if (code == REG || code == SUBREG)
480     {
481       int regnum;
482
483       if (code == REG)
484         regnum = REGNO (op);
485       else
486         regnum = true_regnum (op);
487
488       fprintf (file, "%s", reg_names[regnum]);
489     }
490   else if (code == HIGH)
491     output_addr_const (file, XEXP (op, 0));  
492   else if (code == MEM)
493     output_address (XEXP (op, 0));
494   else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
495     fprintf (file, "%s", reg_names[0]);
496   else if (GET_CODE (op) == CONST_DOUBLE)
497     {
498       if ((CONST_DOUBLE_LOW (op) != 0) || (CONST_DOUBLE_HIGH (op) != 0))
499         output_operand_lossage ("Only 0.0 can be loaded as an immediate");
500       else
501         fprintf (file, "0");
502     }
503   else if (code == EQ)
504     fprintf (file, "e  ");
505   else if (code == NE)
506     fprintf (file, "ne ");
507   else if (code == GT)
508     fprintf (file, "g  ");
509   else if (code == GTU)
510     fprintf (file, "gu ");
511   else if (code == LT)
512     fprintf (file, "l  ");
513   else if (code == LTU)
514     fprintf (file, "lu ");
515   else if (code == GE)
516     fprintf (file, "ge ");
517   else if (code == GEU)
518     fprintf (file, "geu");
519   else if (code == LE)
520     fprintf (file, "le ");
521   else if (code == LEU)
522     fprintf (file, "leu");
523   else
524     output_addr_const (file, op);
525 }
526
527 /* A C compound statement to output to stdio stream STREAM the
528    assembler syntax for an instruction operand that is a memory
529    reference whose address is ADDR.  ADDR is an RTL expression.
530
531    On some machines, the syntax for a symbolic address depends on
532    the section that the address refers to.  On these machines,
533    define the macro `ENCODE_SECTION_INFO' to store the information
534    into the `symbol_ref', and then check for it here.  */
535
536 void
537 lm32_print_operand_address (FILE * file, rtx addr)
538 {
539   switch (GET_CODE (addr))
540     {
541     case REG:
542       fprintf (file, "(%s+0)", reg_names[REGNO (addr)]);
543       break;
544
545     case MEM:
546       output_address (XEXP (addr, 0));
547       break;
548
549     case PLUS:
550       {
551         rtx arg0 = XEXP (addr, 0);
552         rtx arg1 = XEXP (addr, 1);
553
554         if (GET_CODE (arg0) == REG && CONSTANT_P (arg1))
555           {
556             if (GET_CODE (arg1) == CONST_INT)
557               fprintf (file, "(%s+%ld)", reg_names[REGNO (arg0)],
558                        INTVAL (arg1));
559             else
560               {
561                 fprintf (file, "(%s+", reg_names[REGNO (arg0)]);
562                 output_addr_const (file, arg1);
563                 fprintf (file, ")");
564               }
565           }
566         else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
567           output_addr_const (file, addr);
568         else
569           fatal_insn ("bad operand", addr);
570       }
571       break;
572
573     case SYMBOL_REF:
574       if (SYMBOL_REF_SMALL_P (addr))
575         {
576           fprintf (file, "gp(");
577           output_addr_const (file, addr);
578           fprintf (file, ")");
579         }
580       else
581         fatal_insn ("can't use non gp relative absolute address", addr);
582       break;
583
584     default:
585       fatal_insn ("invalid addressing mode", addr);
586       break;
587     }
588 }
589
590 /* Determine where to put an argument to a function.
591    Value is zero to push the argument on the stack,
592    or a hard register in which to store the argument.
593
594    MODE is the argument's machine mode.
595    TYPE is the data type of the argument (as a tree).
596     This is null for libcalls where that information may
597     not be available.
598    CUM is a variable of type CUMULATIVE_ARGS which gives info about
599     the preceding args and about the function being called.
600    NAMED is nonzero if this argument is a named parameter
601     (otherwise it is an extra parameter matching an ellipsis).  */
602
603 rtx
604 lm32_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
605                    tree type, int named)
606 {
607   if (mode == VOIDmode)
608     /* Compute operand 2 of the call insn.  */
609     return GEN_INT (0);
610
611   if (targetm.calls.must_pass_in_stack (mode, type))
612     return NULL_RTX;
613
614   if (!named || (cum + LM32_NUM_REGS2 (mode, type) > LM32_NUM_ARG_REGS))
615     return NULL_RTX;
616
617   return gen_rtx_REG (mode, cum + LM32_FIRST_ARG_REG);
618 }
619
620 HOST_WIDE_INT
621 lm32_compute_initial_elimination_offset (int from, int to)
622 {
623   HOST_WIDE_INT offset = 0;
624
625   switch (from)
626     {
627     case ARG_POINTER_REGNUM:
628       switch (to)
629         {
630         case FRAME_POINTER_REGNUM:
631           offset = 0;
632           break;
633         case STACK_POINTER_REGNUM:
634           offset =
635             lm32_compute_frame_size (get_frame_size ()) -
636             current_frame_info.pretend_size;
637           break;
638         default:
639           gcc_unreachable ();
640         }
641       break;
642     default:
643       gcc_unreachable ();
644     }
645
646   return offset;
647 }
648
649 static void
650 lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode,
651                              tree type, int *pretend_size, int no_rtl)
652 {
653   int first_anon_arg;
654   tree fntype;
655   int stdarg_p;
656
657   fntype = TREE_TYPE (current_function_decl);
658   stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
659               && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
660                   != void_type_node));
661
662   if (stdarg_p)
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 void
700 lm32_override_options (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 && (unsigned HOST_WIDE_INT) 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 }