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