OSDN Git Service

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