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