1 /* Subroutines used for code generation on the Lattice Mico32 architecture.
2 Contributed by Jon Beniston <jon@beniston.com>
4 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
6 This file is part of GCC.
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.
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.
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/>. */
24 #include "coretypes.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"
43 #include "diagnostic-core.h"
48 #include "target-def.h"
49 #include "langhooks.h"
50 #include "tm-constrs.h"
53 struct lm32_frame_info
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. */
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,
73 static bool lm32_can_eliminate (const int, const int);
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,
81 static void lm32_function_arg_advance (CUMULATIVE_ARGS * cum,
82 enum machine_mode mode,
83 const_tree type, bool named);
85 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
86 static const struct default_options lm32_option_optimization_table[] =
88 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
89 { OPT_LEVELS_NONE, 0, NULL, 0 }
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
123 struct gcc_target targetm = TARGET_INITIALIZER;
125 /* Current frame information calculated by lm32_compute_frame_size. */
126 static struct lm32_frame_info current_frame_info;
128 /* Return non-zero if the given return type should be returned in memory. */
131 lm32_return_in_memory (tree type)
135 if (!AGGREGATE_TYPE_P (type))
137 /* All simple types are returned in registers. */
141 size = int_size_in_bytes (type);
142 if (size >= 0 && size <= UNITS_PER_WORD)
144 /* If it can fit in one register. */
151 /* Generate an emit a word sized add instruction. */
154 emit_add (rtx dest, rtx src0, rtx src1)
157 insn = emit_insn (gen_addsi3 (dest, src0, src1));
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
171 gen_int_relational (enum rtx_code code,
177 enum machine_mode mode;
183 mode = GET_MODE (cmp0);
184 if (mode == VOIDmode)
185 mode = GET_MODE (cmp1);
187 /* Is this a branch or compare. */
188 branch_p = (destination != 0);
190 /* Instruction set doesn't support LE or LT, so swap operands and use
201 code = swap_condition (code);
213 rtx insn, cond, label;
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);
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);
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);
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)
247 if (!satisfies_constraint_K (cmp1))
248 cmp1 = force_reg (mode, cmp1);
254 if (!satisfies_constraint_L (cmp1))
255 cmp1 = force_reg (mode, cmp1);
262 /* Generate compare instruction. */
263 emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1));
267 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
268 and OPERAND[3]. Store the result in OPERANDS[0]. */
271 lm32_expand_scc (rtx operands[])
273 rtx target = operands[0];
274 enum rtx_code code = GET_CODE (operands[1]);
275 rtx op0 = operands[2];
276 rtx op1 = operands[3];
278 gen_int_relational (code, target, op0, op1, NULL_RTX);
281 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
282 CODE and jump to OPERANDS[3] if the condition holds. */
285 lm32_expand_conditional_branch (rtx operands[])
287 enum rtx_code code = GET_CODE (operands[0]);
288 rtx op0 = operands[1];
289 rtx op1 = operands[2];
290 rtx destination = operands[3];
292 gen_int_relational (code, NULL_RTX, op0, op1, destination);
295 /* Generate and emit RTL to save or restore callee save registers. */
297 expand_save_restore (struct lm32_frame_info *info, int op)
299 unsigned int reg_save_mask = info->reg_save_mask;
301 HOST_WIDE_INT offset;
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++)
308 if ((reg_save_mask & (1 << regno)) != 0)
313 offset_rtx = GEN_INT (offset);
314 if (satisfies_constraint_K (offset_rtx))
316 mem = gen_rtx_MEM (word_mode,
323 /* r10 is caller saved so it can be used as a temp reg. */
326 r10 = gen_rtx_REG (word_mode, 10);
327 insn = emit_move_insn (r10, offset_rtx);
329 RTX_FRAME_RELATED_P (insn) = 1;
330 insn = emit_add (r10, r10, stack_pointer_rtx);
332 RTX_FRAME_RELATED_P (insn) = 1;
333 mem = gen_rtx_MEM (word_mode, r10);
337 insn = emit_move_insn (mem, gen_rtx_REG (word_mode, regno));
339 insn = emit_move_insn (gen_rtx_REG (word_mode, regno), mem);
341 /* only prologue instructions which set the sp fp or save a
342 register should be marked as frame related. */
344 RTX_FRAME_RELATED_P (insn) = 1;
345 offset -= UNITS_PER_WORD;
351 stack_adjust (HOST_WIDE_INT amount)
355 if (!IN_RANGE (amount, -32776, 32768))
357 /* r10 is caller saved so it can be used as a temp reg. */
359 r10 = gen_rtx_REG (word_mode, 10);
360 insn = emit_move_insn (r10, GEN_INT (amount));
362 RTX_FRAME_RELATED_P (insn) = 1;
363 insn = emit_add (stack_pointer_rtx, stack_pointer_rtx, r10);
365 RTX_FRAME_RELATED_P (insn) = 1;
369 insn = emit_add (stack_pointer_rtx,
370 stack_pointer_rtx, GEN_INT (amount));
372 RTX_FRAME_RELATED_P (insn) = 1;
377 /* Create and emit instructions for a functions prologue. */
379 lm32_expand_prologue (void)
383 lm32_compute_frame_size (get_frame_size ());
385 if (current_frame_info.total_size > 0)
387 /* Add space on stack new frame. */
388 stack_adjust (-current_frame_info.total_size);
390 /* Save callee save registers. */
391 if (current_frame_info.reg_save_mask != 0)
392 expand_save_restore (¤t_frame_info, 0);
394 /* Setup frame pointer if it's needed. */
395 if (frame_pointer_needed == 1)
398 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
399 RTX_FRAME_RELATED_P (insn) = 1;
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,
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;
411 /* Prevent prologue from being scheduled into function body. */
412 emit_insn (gen_blockage ());
416 /* Create an emit instructions for a functions epilogue. */
418 lm32_expand_epilogue (void)
420 rtx ra_rtx = gen_rtx_REG (Pmode, RA_REGNUM);
422 lm32_compute_frame_size (get_frame_size ());
424 if (current_frame_info.total_size > 0)
426 /* Prevent stack code from being reordered. */
427 emit_insn (gen_blockage ());
429 /* Restore callee save registers. */
430 if (current_frame_info.reg_save_mask != 0)
431 expand_save_restore (¤t_frame_info, 1);
433 /* Deallocate stack. */
434 stack_adjust (current_frame_info.total_size);
436 /* Return to calling function. */
437 emit_jump_insn (gen_return_internal (ra_rtx));
441 /* Return to calling function. */
442 emit_jump_insn (gen_return_internal (ra_rtx));
446 /* Return the bytes needed to compute the frame pointer from the current
449 lm32_compute_frame_size (int size)
452 HOST_WIDE_INT total_size, locals_size, args_size, pretend_size, callee_size;
453 unsigned int reg_save_mask;
456 args_size = crtl->outgoing_args_size;
457 pretend_size = crtl->args.pretend_args_size;
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++)
465 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
467 reg_save_mask |= 1 << regno;
468 callee_size += UNITS_PER_WORD;
471 if (df_regs_ever_live_p (RA_REGNUM) || !current_function_is_leaf
474 reg_save_mask |= 1 << RA_REGNUM;
475 callee_size += UNITS_PER_WORD;
477 if (!(reg_save_mask & (1 << FP_REGNUM)) && frame_pointer_needed)
479 reg_save_mask |= 1 << FP_REGNUM;
480 callee_size += UNITS_PER_WORD;
483 /* Compute total frame size. */
484 total_size = pretend_size + args_size + locals_size + callee_size;
486 /* Align frame to appropriate boundary. */
487 total_size = (total_size + 3) & ~3;
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;
501 lm32_print_operand (FILE * file, rtx op, int letter)
505 code = GET_CODE (op);
507 if (code == SIGN_EXTEND)
508 op = XEXP (op, 0), code = GET_CODE (op);
509 else if (code == REG || code == SUBREG)
516 regnum = true_regnum (op);
518 fprintf (file, "%s", reg_names[regnum]);
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)
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");
534 fprintf (file, "e ");
536 fprintf (file, "ne ");
538 fprintf (file, "g ");
539 else if (code == GTU)
540 fprintf (file, "gu ");
542 fprintf (file, "l ");
543 else if (code == LTU)
544 fprintf (file, "lu ");
546 fprintf (file, "ge ");
547 else if (code == GEU)
548 fprintf (file, "geu");
550 fprintf (file, "le ");
551 else if (code == LEU)
552 fprintf (file, "leu");
554 output_addr_const (file, op);
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.
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. */
567 lm32_print_operand_address (FILE * file, rtx addr)
569 switch (GET_CODE (addr))
572 fprintf (file, "(%s+0)", reg_names[REGNO (addr)]);
576 output_address (XEXP (addr, 0));
581 rtx arg0 = XEXP (addr, 0);
582 rtx arg1 = XEXP (addr, 1);
584 if (GET_CODE (arg0) == REG && CONSTANT_P (arg1))
586 if (GET_CODE (arg1) == CONST_INT)
587 fprintf (file, "(%s+%ld)", reg_names[REGNO (arg0)],
591 fprintf (file, "(%s+", reg_names[REGNO (arg0)]);
592 output_addr_const (file, arg1);
596 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
597 output_addr_const (file, addr);
599 fatal_insn ("bad operand", addr);
604 if (SYMBOL_REF_SMALL_P (addr))
606 fprintf (file, "gp(");
607 output_addr_const (file, addr);
611 fatal_insn ("can't use non gp relative absolute address", addr);
615 fatal_insn ("invalid addressing mode", addr);
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.
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
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). */
634 lm32_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
635 const_tree type, bool named)
637 if (mode == VOIDmode)
638 /* Compute operand 2 of the call insn. */
641 if (targetm.calls.must_pass_in_stack (mode, type))
644 if (!named || (*cum + LM32_NUM_REGS2 (mode, type) > LM32_NUM_ARG_REGS))
647 return gen_rtx_REG (mode, *cum + LM32_FIRST_ARG_REG);
651 lm32_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
652 const_tree type, bool named ATTRIBUTE_UNUSED)
654 *cum += LM32_NUM_REGS2 (mode, type);
658 lm32_compute_initial_elimination_offset (int from, int to)
660 HOST_WIDE_INT offset = 0;
664 case ARG_POINTER_REGNUM:
667 case FRAME_POINTER_REGNUM:
670 case STACK_POINTER_REGNUM:
672 lm32_compute_frame_size (get_frame_size ()) -
673 current_frame_info.pretend_size;
687 lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode,
688 tree type, int *pretend_size, int no_rtl)
693 fntype = TREE_TYPE (current_function_decl);
695 if (stdarg_p (fntype))
696 first_anon_arg = *cum + LM32_FIRST_ARG_REG;
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. */
707 size = int_size_in_bytes (type);
709 size = GET_MODE_SIZE (mode);
712 *cum + LM32_FIRST_ARG_REG +
713 ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
716 if ((first_anon_arg < (LM32_FIRST_ARG_REG + LM32_NUM_ARG_REGS)) && !no_rtl)
718 int first_reg_offset = first_anon_arg;
719 int size = LM32_FIRST_ARG_REG + LM32_NUM_ARG_REGS - first_anon_arg;
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);
727 *pretend_size = size * UNITS_PER_WORD;
731 /* Override command line options. */
733 lm32_option_override (void)
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;
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
744 lm32_can_use_return (void)
746 if (!reload_completed)
749 if (df_regs_ever_live_p (RA_REGNUM) || crtl->profile)
752 if (lm32_compute_frame_size (get_frame_size ()) != 0)
758 /* Support function to determine the return address of the function
759 'count' frames back up the stack. */
761 lm32_return_addr_rtx (int count, rtx frame)
766 if (!df_regs_ever_live_p (RA_REGNUM))
767 r = gen_rtx_REG (Pmode, RA_REGNUM);
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 ());
776 else if (flag_omit_frame_pointer)
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 ());
788 /* Return true if EXP should be placed in the small data section. */
791 lm32_in_small_data_p (const_tree exp)
793 /* We want to merge strings, so we never consider them small data. */
794 if (TREE_CODE (exp) == STRING_CST)
797 /* Functions are never in the small data area. Duh. */
798 if (TREE_CODE (exp) == FUNCTION_DECL)
801 if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
803 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
804 if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0)
809 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
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)
820 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
821 Assume that the areas do not overlap. */
824 lm32_block_move_inline (rtx dest, rtx src, HOST_WIDE_INT length,
825 HOST_WIDE_INT alignment)
827 HOST_WIDE_INT offset, delta;
828 unsigned HOST_WIDE_INT bits;
830 enum machine_mode mode;
833 /* Work out how many bits to move at a time. */
847 mode = mode_for_size (bits, MODE_INT, 0);
848 delta = bits / BITS_PER_UNIT;
850 /* Allocate a buffer for the temporary registers. */
851 regs = XALLOCAVEC (rtx, length / delta);
853 /* Load as many BITS-sized chunks as possible. */
854 for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
856 regs[i] = gen_reg_rtx (mode);
857 emit_move_insn (regs[i], adjust_address (src, mode, offset));
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]);
864 /* Mop up any left-over bytes. */
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);
874 /* Expand string/block move operations.
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. */
882 lm32_expand_block_move (rtx * operands)
884 if ((GET_CODE (operands[2]) == CONST_INT) && (INTVAL (operands[2]) <= 32))
886 lm32_block_move_inline (operands[0], operands[1], INTVAL (operands[2]),
887 INTVAL (operands[3]));
893 /* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol
894 isn't protected by a PIC unspec. */
896 nonpic_symbol_mentioned_p (rtx x)
901 if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF
902 || GET_CODE (x) == PC)
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)
910 if (GET_CODE (x) == UNSPEC)
913 fmt = GET_RTX_FORMAT (GET_CODE (x));
914 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
920 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
921 if (nonpic_symbol_mentioned_p (XVECEXP (x, i, j)))
924 else if (fmt[i] == 'e' && nonpic_symbol_mentioned_p (XEXP (x, i)))
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. */
936 lm32_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
938 enum machine_mode mode = GET_MODE (x);
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;
948 /* Determine if we can handle the given mode size in a single instruction. */
949 small_mode = (mode == QImode) || (mode == HImode) || (mode == SImode);
962 *total = COSTS_N_INSNS (LM32_NUM_REGS (mode));
965 COSTS_N_INSNS (arithmetic_latency + (LM32_NUM_REGS (mode) - 1));
972 *total = COSTS_N_INSNS (1);
974 *total = COSTS_N_INSNS (compare_latency);
978 /* FIXME. Guessing here. */
979 *total = COSTS_N_INSNS (LM32_NUM_REGS (mode) * (2 + 3) / 2);
986 if (TARGET_BARREL_SHIFT_ENABLED && small_mode)
989 *total = COSTS_N_INSNS (1);
991 *total = COSTS_N_INSNS (shift_latency);
993 else if (TARGET_BARREL_SHIFT_ENABLED)
995 /* FIXME: Guessing here. */
996 *total = COSTS_N_INSNS (LM32_NUM_REGS (mode) * 4);
998 else if (small_mode && GET_CODE (XEXP (x, 1)) == CONST_INT)
1000 *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
1006 *total = COSTS_N_INSNS (libcall_size_cost);
1008 *total = COSTS_N_INSNS (100);
1013 if (TARGET_MULTIPLY_ENABLED && small_mode)
1016 *total = COSTS_N_INSNS (1);
1018 *total = COSTS_N_INSNS (multiply_latency);
1024 *total = COSTS_N_INSNS (libcall_size_cost);
1026 *total = COSTS_N_INSNS (100);
1034 if (TARGET_DIVIDE_ENABLED && small_mode)
1037 *total = COSTS_N_INSNS (1);
1040 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1043 unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
1050 if (IN_RANGE (i, 0, 65536))
1051 *total = COSTS_N_INSNS (1 + 1 + cycles);
1053 *total = COSTS_N_INSNS (2 + 1 + cycles);
1056 else if (GET_CODE (XEXP (x, 1)) == REG)
1058 *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode) / 2);
1063 *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode) / 2);
1072 *total = COSTS_N_INSNS (libcall_size_cost);
1074 *total = COSTS_N_INSNS (100);
1081 *total = COSTS_N_INSNS (1);
1083 *total = COSTS_N_INSNS (arithmetic_latency);
1087 if (MEM_P (XEXP (x, 0)))
1088 *total = COSTS_N_INSNS (0);
1089 else if (small_mode)
1092 *total = COSTS_N_INSNS (1);
1094 *total = COSTS_N_INSNS (arithmetic_latency);
1097 *total = COSTS_N_INSNS (LM32_NUM_REGS (mode) / 2);
1106 *total = COSTS_N_INSNS (0);
1117 if (satisfies_constraint_L (x))
1118 *total = COSTS_N_INSNS (0);
1120 *total = COSTS_N_INSNS (2);
1127 if (satisfies_constraint_K (x))
1128 *total = COSTS_N_INSNS (0);
1130 *total = COSTS_N_INSNS (2);
1134 if (TARGET_MULTIPLY_ENABLED)
1136 if (satisfies_constraint_K (x))
1137 *total = COSTS_N_INSNS (0);
1139 *total = COSTS_N_INSNS (2);
1145 if (satisfies_constraint_K (x))
1146 *total = COSTS_N_INSNS (1);
1148 *total = COSTS_N_INSNS (2);
1159 *total = COSTS_N_INSNS (0);
1166 *total = COSTS_N_INSNS (0);
1175 *total = COSTS_N_INSNS (2);
1179 *total = COSTS_N_INSNS (1);
1184 *total = COSTS_N_INSNS (1);
1186 *total = COSTS_N_INSNS (load_latency);
1194 /* Implemenent TARGET_CAN_ELIMINATE. */
1197 lm32_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
1199 return (to == STACK_POINTER_REGNUM && frame_pointer_needed) ? false : true;
1202 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1205 lm32_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict)
1208 if (strict && REG_P (x) && STRICT_REG_OK_FOR_BASE_P (x))
1210 if (!strict && REG_P (x) && NONSTRICT_REG_OK_FOR_BASE_P (x))
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)))
1223 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
1229 /* Check a move is not memory to memory. */
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);
1238 /* Implement LEGITIMATE_CONSTANT_P. */
1241 lm32_legitimate_constant_p (rtx x)
1243 /* 32-bit addresses require multiple instructions. */
1244 if (!flag_pic && reloc_operand (x, GET_MODE (x)))