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"
49 #include "target-def.h"
50 #include "langhooks.h"
51 #include "tm-constrs.h"
54 struct lm32_frame_info
56 HOST_WIDE_INT total_size
; /* number of bytes of entire frame. */
57 HOST_WIDE_INT callee_size
; /* number of bytes to save callee saves. */
58 HOST_WIDE_INT pretend_size
; /* number of bytes we pretend caller did. */
59 HOST_WIDE_INT args_size
; /* number of bytes for outgoing arguments. */
60 HOST_WIDE_INT locals_size
; /* number of bytes for local variables. */
61 unsigned int reg_save_mask
; /* mask of saved registers. */
64 /* Prototypes for static functions. */
65 static rtx
emit_add (rtx dest
, rtx src0
, rtx src1
);
66 static void expand_save_restore (struct lm32_frame_info
*info
, int op
);
67 static void stack_adjust (HOST_WIDE_INT amount
);
68 static bool lm32_in_small_data_p (const_tree
);
69 static void lm32_setup_incoming_varargs (CUMULATIVE_ARGS
* cum
,
70 enum machine_mode mode
, tree type
,
71 int *pretend_size
, int no_rtl
);
72 static bool lm32_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
74 static bool lm32_can_eliminate (const int, const int);
76 lm32_legitimate_address_p (enum machine_mode mode
, rtx x
, bool strict
);
77 static HOST_WIDE_INT
lm32_compute_frame_size (int size
);
78 static bool lm32_handle_option (size_t code
, const char *arg
, int value
);
79 static void lm32_option_override (void);
81 #undef TARGET_HANDLE_OPTION
82 #define TARGET_HANDLE_OPTION lm32_handle_option
83 #undef TARGET_OPTION_OVERRIDE
84 #define TARGET_OPTION_OVERRIDE lm32_option_override
85 #undef TARGET_ADDRESS_COST
86 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
87 #undef TARGET_RTX_COSTS
88 #define TARGET_RTX_COSTS lm32_rtx_costs
89 #undef TARGET_IN_SMALL_DATA_P
90 #define TARGET_IN_SMALL_DATA_P lm32_in_small_data_p
91 #undef TARGET_PROMOTE_FUNCTION_MODE
92 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
93 #undef TARGET_SETUP_INCOMING_VARARGS
94 #define TARGET_SETUP_INCOMING_VARARGS lm32_setup_incoming_varargs
95 #undef TARGET_PROMOTE_PROTOTYPES
96 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
97 #undef TARGET_MIN_ANCHOR_OFFSET
98 #define TARGET_MIN_ANCHOR_OFFSET -0x8000
99 #undef TARGET_MAX_ANCHOR_OFFSET
100 #define TARGET_MAX_ANCHOR_OFFSET 0x7fff
101 #undef TARGET_CAN_ELIMINATE
102 #define TARGET_CAN_ELIMINATE lm32_can_eliminate
103 #undef TARGET_LEGITIMATE_ADDRESS_P
104 #define TARGET_LEGITIMATE_ADDRESS_P lm32_legitimate_address_p
106 struct gcc_target targetm
= TARGET_INITIALIZER
;
108 /* Current frame information calculated by lm32_compute_frame_size. */
109 static struct lm32_frame_info current_frame_info
;
111 /* Return non-zero if the given return type should be returned in memory. */
114 lm32_return_in_memory (tree type
)
118 if (!AGGREGATE_TYPE_P (type
))
120 /* All simple types are returned in registers. */
124 size
= int_size_in_bytes (type
);
125 if (size
>= 0 && size
<= UNITS_PER_WORD
)
127 /* If it can fit in one register. */
134 /* Generate an emit a word sized add instruction. */
137 emit_add (rtx dest
, rtx src0
, rtx src1
)
140 insn
= emit_insn (gen_addsi3 (dest
, src0
, src1
));
144 /* Generate the code to compare (and possibly branch) two integer values
145 TEST_CODE is the comparison code we are trying to emulate
146 (or implement directly)
147 RESULT is where to store the result of the comparison,
148 or null to emit a branch
149 CMP0 CMP1 are the two comparison operands
150 DESTINATION is the destination of the branch, or null to only compare
154 gen_int_relational (enum rtx_code code
,
160 enum machine_mode mode
;
163 mode
= GET_MODE (cmp0
);
164 if (mode
== VOIDmode
)
165 mode
= GET_MODE (cmp1
);
167 /* Is this a branch or compare. */
168 branch_p
= (destination
!= 0);
170 /* Instruction set doesn't support LE or LT, so swap operands and use
178 code
= swap_condition (code
);
191 /* Operands must be in registers. */
192 if (!register_operand (cmp0
, mode
))
193 cmp0
= force_reg (mode
, cmp0
);
194 if (!register_operand (cmp1
, mode
))
195 cmp1
= force_reg (mode
, cmp1
);
197 /* Generate conditional branch instruction. */
198 rtx cond
= gen_rtx_fmt_ee (code
, mode
, cmp0
, cmp1
);
199 rtx label
= gen_rtx_LABEL_REF (VOIDmode
, destination
);
200 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
,
201 gen_rtx_IF_THEN_ELSE (VOIDmode
,
202 cond
, label
, pc_rtx
));
203 emit_jump_insn (insn
);
207 /* We can't have const_ints in cmp0, other than 0. */
208 if ((GET_CODE (cmp0
) == CONST_INT
) && (INTVAL (cmp0
) != 0))
209 cmp0
= force_reg (mode
, cmp0
);
211 /* If the comparison is against an int not in legal range
212 move it into a register. */
213 if (GET_CODE (cmp1
) == CONST_INT
)
223 if (!satisfies_constraint_K (cmp1
))
224 cmp1
= force_reg (mode
, cmp1
);
230 if (!satisfies_constraint_L (cmp1
))
231 cmp1
= force_reg (mode
, cmp1
);
238 /* Generate compare instruction. */
239 emit_move_insn (result
, gen_rtx_fmt_ee (code
, mode
, cmp0
, cmp1
));
243 /* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
244 and OPERAND[3]. Store the result in OPERANDS[0]. */
247 lm32_expand_scc (rtx operands
[])
249 rtx target
= operands
[0];
250 enum rtx_code code
= GET_CODE (operands
[1]);
251 rtx op0
= operands
[2];
252 rtx op1
= operands
[3];
254 gen_int_relational (code
, target
, op0
, op1
, NULL_RTX
);
257 /* Compare OPERANDS[1] with OPERANDS[2] using comparison code
258 CODE and jump to OPERANDS[3] if the condition holds. */
261 lm32_expand_conditional_branch (rtx operands
[])
263 enum rtx_code code
= GET_CODE (operands
[0]);
264 rtx op0
= operands
[1];
265 rtx op1
= operands
[2];
266 rtx destination
= operands
[3];
268 gen_int_relational (code
, NULL_RTX
, op0
, op1
, destination
);
271 /* Generate and emit RTL to save or restore callee save registers. */
273 expand_save_restore (struct lm32_frame_info
*info
, int op
)
275 unsigned int reg_save_mask
= info
->reg_save_mask
;
277 HOST_WIDE_INT offset
;
280 /* Callee saves are below locals and above outgoing arguments. */
281 offset
= info
->args_size
+ info
->callee_size
;
282 for (regno
= 0; regno
<= 31; regno
++)
284 if ((reg_save_mask
& (1 << regno
)) != 0)
289 offset_rtx
= GEN_INT (offset
);
290 if (satisfies_constraint_K (offset_rtx
))
292 mem
= gen_rtx_MEM (word_mode
,
299 /* r10 is caller saved so it can be used as a temp reg. */
302 r10
= gen_rtx_REG (word_mode
, 10);
303 insn
= emit_move_insn (r10
, offset_rtx
);
305 RTX_FRAME_RELATED_P (insn
) = 1;
306 insn
= emit_add (r10
, r10
, stack_pointer_rtx
);
308 RTX_FRAME_RELATED_P (insn
) = 1;
309 mem
= gen_rtx_MEM (word_mode
, r10
);
313 insn
= emit_move_insn (mem
, gen_rtx_REG (word_mode
, regno
));
315 insn
= emit_move_insn (gen_rtx_REG (word_mode
, regno
), mem
);
317 /* only prologue instructions which set the sp fp or save a
318 register should be marked as frame related. */
320 RTX_FRAME_RELATED_P (insn
) = 1;
321 offset
-= UNITS_PER_WORD
;
327 stack_adjust (HOST_WIDE_INT amount
)
331 if (!IN_RANGE (amount
, -32776, 32768))
333 /* r10 is caller saved so it can be used as a temp reg. */
335 r10
= gen_rtx_REG (word_mode
, 10);
336 insn
= emit_move_insn (r10
, GEN_INT (amount
));
338 RTX_FRAME_RELATED_P (insn
) = 1;
339 insn
= emit_add (stack_pointer_rtx
, stack_pointer_rtx
, r10
);
341 RTX_FRAME_RELATED_P (insn
) = 1;
345 insn
= emit_add (stack_pointer_rtx
,
346 stack_pointer_rtx
, GEN_INT (amount
));
348 RTX_FRAME_RELATED_P (insn
) = 1;
353 /* Create and emit instructions for a functions prologue. */
355 lm32_expand_prologue (void)
359 lm32_compute_frame_size (get_frame_size ());
361 if (current_frame_info
.total_size
> 0)
363 /* Add space on stack new frame. */
364 stack_adjust (-current_frame_info
.total_size
);
366 /* Save callee save registers. */
367 if (current_frame_info
.reg_save_mask
!= 0)
368 expand_save_restore (¤t_frame_info
, 0);
370 /* Setup frame pointer if it's needed. */
371 if (frame_pointer_needed
== 1)
373 /* Load offset - Don't use total_size, as that includes pretend_size,
374 which isn't part of this frame? */
376 emit_move_insn (frame_pointer_rtx
,
377 GEN_INT (current_frame_info
.args_size
+
378 current_frame_info
.callee_size
+
379 current_frame_info
.locals_size
));
380 RTX_FRAME_RELATED_P (insn
) = 1;
383 insn
= emit_add (frame_pointer_rtx
,
384 frame_pointer_rtx
, stack_pointer_rtx
);
385 RTX_FRAME_RELATED_P (insn
) = 1;
388 /* Prevent prologue from being scheduled into function body. */
389 emit_insn (gen_blockage ());
393 /* Create an emit instructions for a functions epilogue. */
395 lm32_expand_epilogue (void)
397 rtx ra_rtx
= gen_rtx_REG (Pmode
, RA_REGNUM
);
399 lm32_compute_frame_size (get_frame_size ());
401 if (current_frame_info
.total_size
> 0)
403 /* Prevent stack code from being reordered. */
404 emit_insn (gen_blockage ());
406 /* Restore callee save registers. */
407 if (current_frame_info
.reg_save_mask
!= 0)
408 expand_save_restore (¤t_frame_info
, 1);
410 /* Deallocate stack. */
411 stack_adjust (current_frame_info
.total_size
);
413 /* Return to calling function. */
414 emit_jump_insn (gen_return_internal (ra_rtx
));
418 /* Return to calling function. */
419 emit_jump_insn (gen_return_internal (ra_rtx
));
423 /* Return the bytes needed to compute the frame pointer from the current
426 lm32_compute_frame_size (int size
)
429 HOST_WIDE_INT total_size
, locals_size
, args_size
, pretend_size
, callee_size
;
430 unsigned int reg_save_mask
;
433 args_size
= crtl
->outgoing_args_size
;
434 pretend_size
= crtl
->args
.pretend_args_size
;
438 /* Build mask that actually determines which regsiters we save
439 and calculate size required to store them in the stack. */
440 for (regno
= 1; regno
< SP_REGNUM
; regno
++)
442 if (df_regs_ever_live_p (regno
) && !call_used_regs
[regno
])
444 reg_save_mask
|= 1 << regno
;
445 callee_size
+= UNITS_PER_WORD
;
448 if (df_regs_ever_live_p (RA_REGNUM
) || !current_function_is_leaf
451 reg_save_mask
|= 1 << RA_REGNUM
;
452 callee_size
+= UNITS_PER_WORD
;
454 if (!(reg_save_mask
& (1 << FP_REGNUM
)) && frame_pointer_needed
)
456 reg_save_mask
|= 1 << FP_REGNUM
;
457 callee_size
+= UNITS_PER_WORD
;
460 /* Compute total frame size. */
461 total_size
= pretend_size
+ args_size
+ locals_size
+ callee_size
;
463 /* Align frame to appropriate boundary. */
464 total_size
= (total_size
+ 3) & ~3;
466 /* Save computed information. */
467 current_frame_info
.total_size
= total_size
;
468 current_frame_info
.callee_size
= callee_size
;
469 current_frame_info
.pretend_size
= pretend_size
;
470 current_frame_info
.locals_size
= locals_size
;
471 current_frame_info
.args_size
= args_size
;
472 current_frame_info
.reg_save_mask
= reg_save_mask
;
478 lm32_print_operand (FILE * file
, rtx op
, int letter
)
482 code
= GET_CODE (op
);
484 if (code
== SIGN_EXTEND
)
485 op
= XEXP (op
, 0), code
= GET_CODE (op
);
486 else if (code
== REG
|| code
== SUBREG
)
493 regnum
= true_regnum (op
);
495 fprintf (file
, "%s", reg_names
[regnum
]);
497 else if (code
== HIGH
)
498 output_addr_const (file
, XEXP (op
, 0));
499 else if (code
== MEM
)
500 output_address (XEXP (op
, 0));
501 else if (letter
== 'z' && GET_CODE (op
) == CONST_INT
&& INTVAL (op
) == 0)
502 fprintf (file
, "%s", reg_names
[0]);
503 else if (GET_CODE (op
) == CONST_DOUBLE
)
505 if ((CONST_DOUBLE_LOW (op
) != 0) || (CONST_DOUBLE_HIGH (op
) != 0))
506 output_operand_lossage ("Only 0.0 can be loaded as an immediate");
511 fprintf (file
, "e ");
513 fprintf (file
, "ne ");
515 fprintf (file
, "g ");
516 else if (code
== GTU
)
517 fprintf (file
, "gu ");
519 fprintf (file
, "l ");
520 else if (code
== LTU
)
521 fprintf (file
, "lu ");
523 fprintf (file
, "ge ");
524 else if (code
== GEU
)
525 fprintf (file
, "geu");
527 fprintf (file
, "le ");
528 else if (code
== LEU
)
529 fprintf (file
, "leu");
531 output_addr_const (file
, op
);
534 /* A C compound statement to output to stdio stream STREAM the
535 assembler syntax for an instruction operand that is a memory
536 reference whose address is ADDR. ADDR is an RTL expression.
538 On some machines, the syntax for a symbolic address depends on
539 the section that the address refers to. On these machines,
540 define the macro `ENCODE_SECTION_INFO' to store the information
541 into the `symbol_ref', and then check for it here. */
544 lm32_print_operand_address (FILE * file
, rtx addr
)
546 switch (GET_CODE (addr
))
549 fprintf (file
, "(%s+0)", reg_names
[REGNO (addr
)]);
553 output_address (XEXP (addr
, 0));
558 rtx arg0
= XEXP (addr
, 0);
559 rtx arg1
= XEXP (addr
, 1);
561 if (GET_CODE (arg0
) == REG
&& CONSTANT_P (arg1
))
563 if (GET_CODE (arg1
) == CONST_INT
)
564 fprintf (file
, "(%s+%ld)", reg_names
[REGNO (arg0
)],
568 fprintf (file
, "(%s+", reg_names
[REGNO (arg0
)]);
569 output_addr_const (file
, arg1
);
573 else if (CONSTANT_P (arg0
) && CONSTANT_P (arg1
))
574 output_addr_const (file
, addr
);
576 fatal_insn ("bad operand", addr
);
581 if (SYMBOL_REF_SMALL_P (addr
))
583 fprintf (file
, "gp(");
584 output_addr_const (file
, addr
);
588 fatal_insn ("can't use non gp relative absolute address", addr
);
592 fatal_insn ("invalid addressing mode", addr
);
597 /* Determine where to put an argument to a function.
598 Value is zero to push the argument on the stack,
599 or a hard register in which to store the argument.
601 MODE is the argument's machine mode.
602 TYPE is the data type of the argument (as a tree).
603 This is null for libcalls where that information may
605 CUM is a variable of type CUMULATIVE_ARGS which gives info about
606 the preceding args and about the function being called.
607 NAMED is nonzero if this argument is a named parameter
608 (otherwise it is an extra parameter matching an ellipsis). */
611 lm32_function_arg (CUMULATIVE_ARGS cum
, enum machine_mode mode
,
612 tree type
, int named
)
614 if (mode
== VOIDmode
)
615 /* Compute operand 2 of the call insn. */
618 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
621 if (!named
|| (cum
+ LM32_NUM_REGS2 (mode
, type
) > LM32_NUM_ARG_REGS
))
624 return gen_rtx_REG (mode
, cum
+ LM32_FIRST_ARG_REG
);
628 lm32_compute_initial_elimination_offset (int from
, int to
)
630 HOST_WIDE_INT offset
= 0;
634 case ARG_POINTER_REGNUM
:
637 case FRAME_POINTER_REGNUM
:
640 case STACK_POINTER_REGNUM
:
642 lm32_compute_frame_size (get_frame_size ()) -
643 current_frame_info
.pretend_size
;
657 lm32_setup_incoming_varargs (CUMULATIVE_ARGS
* cum
, enum machine_mode mode
,
658 tree type
, int *pretend_size
, int no_rtl
)
663 fntype
= TREE_TYPE (current_function_decl
);
665 if (stdarg_p (fntype
))
666 first_anon_arg
= *cum
+ LM32_FIRST_ARG_REG
;
669 /* this is the common case, we have been passed details setup
670 for the last named argument, we want to skip over the
671 registers, if any used in passing this named paramter in
672 order to determine which is the first registers used to pass
673 anonymous arguments. */
677 size
= int_size_in_bytes (type
);
679 size
= GET_MODE_SIZE (mode
);
682 *cum
+ LM32_FIRST_ARG_REG
+
683 ((size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
686 if ((first_anon_arg
< (LM32_FIRST_ARG_REG
+ LM32_NUM_ARG_REGS
)) && !no_rtl
)
688 int first_reg_offset
= first_anon_arg
;
689 int size
= LM32_FIRST_ARG_REG
+ LM32_NUM_ARG_REGS
- first_anon_arg
;
692 regblock
= gen_rtx_MEM (BLKmode
,
693 plus_constant (arg_pointer_rtx
,
694 FIRST_PARM_OFFSET (0)));
695 move_block_from_reg (first_reg_offset
, regblock
, size
);
697 *pretend_size
= size
* UNITS_PER_WORD
;
701 /* Implement TARGET_HANDLE_OPTION. */
704 lm32_handle_option (size_t code
, const char *arg ATTRIBUTE_UNUSED
, int value
)
709 g_switch_value
= value
;
718 /* Override command line options. */
720 lm32_option_override (void)
722 /* We must have sign-extend enabled if barrel-shift isn't. */
723 if (!TARGET_BARREL_SHIFT_ENABLED
&& !TARGET_SIGN_EXTEND_ENABLED
)
724 target_flags
|= MASK_SIGN_EXTEND_ENABLED
;
727 /* Return nonzero if this function is known to have a null epilogue.
728 This allows the optimizer to omit jumps to jumps if no stack
731 lm32_can_use_return (void)
733 if (!reload_completed
)
736 if (df_regs_ever_live_p (RA_REGNUM
) || crtl
->profile
)
739 if (lm32_compute_frame_size (get_frame_size ()) != 0)
745 /* Support function to determine the return address of the function
746 'count' frames back up the stack. */
748 lm32_return_addr_rtx (int count
, rtx frame
)
753 if (!df_regs_ever_live_p (RA_REGNUM
))
754 r
= gen_rtx_REG (Pmode
, RA_REGNUM
);
757 r
= gen_rtx_MEM (Pmode
,
758 gen_rtx_PLUS (Pmode
, frame
,
759 GEN_INT (-2 * UNITS_PER_WORD
)));
760 set_mem_alias_set (r
, get_frame_alias_set ());
763 else if (flag_omit_frame_pointer
)
767 r
= gen_rtx_MEM (Pmode
,
768 gen_rtx_PLUS (Pmode
, frame
,
769 GEN_INT (-2 * UNITS_PER_WORD
)));
770 set_mem_alias_set (r
, get_frame_alias_set ());
775 /* Return true if EXP should be placed in the small data section. */
778 lm32_in_small_data_p (const_tree exp
)
780 /* We want to merge strings, so we never consider them small data. */
781 if (TREE_CODE (exp
) == STRING_CST
)
784 /* Functions are never in the small data area. Duh. */
785 if (TREE_CODE (exp
) == FUNCTION_DECL
)
788 if (TREE_CODE (exp
) == VAR_DECL
&& DECL_SECTION_NAME (exp
))
790 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (exp
));
791 if (strcmp (section
, ".sdata") == 0 || strcmp (section
, ".sbss") == 0)
796 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (exp
));
798 /* If this is an incomplete type with size 0, then we can't put it
799 in sdata because it might be too big when completed. */
800 if (size
> 0 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
)
807 /* Emit straight-line code to move LENGTH bytes from SRC to DEST.
808 Assume that the areas do not overlap. */
811 lm32_block_move_inline (rtx dest
, rtx src
, HOST_WIDE_INT length
,
812 HOST_WIDE_INT alignment
)
814 HOST_WIDE_INT offset
, delta
;
815 unsigned HOST_WIDE_INT bits
;
817 enum machine_mode mode
;
820 /* Work out how many bits to move at a time. */
834 mode
= mode_for_size (bits
, MODE_INT
, 0);
835 delta
= bits
/ BITS_PER_UNIT
;
837 /* Allocate a buffer for the temporary registers. */
838 regs
= alloca (sizeof (rtx
) * length
/ delta
);
840 /* Load as many BITS-sized chunks as possible. */
841 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
843 regs
[i
] = gen_reg_rtx (mode
);
844 emit_move_insn (regs
[i
], adjust_address (src
, mode
, offset
));
847 /* Copy the chunks to the destination. */
848 for (offset
= 0, i
= 0; offset
+ delta
<= length
; offset
+= delta
, i
++)
849 emit_move_insn (adjust_address (dest
, mode
, offset
), regs
[i
]);
851 /* Mop up any left-over bytes. */
854 src
= adjust_address (src
, BLKmode
, offset
);
855 dest
= adjust_address (dest
, BLKmode
, offset
);
856 move_by_pieces (dest
, src
, length
- offset
,
857 MIN (MEM_ALIGN (src
), MEM_ALIGN (dest
)), 0);
861 /* Expand string/block move operations.
863 operands[0] is the pointer to the destination.
864 operands[1] is the pointer to the source.
865 operands[2] is the number of bytes to move.
866 operands[3] is the alignment. */
869 lm32_expand_block_move (rtx
* operands
)
871 if ((GET_CODE (operands
[2]) == CONST_INT
) && (INTVAL (operands
[2]) <= 32))
873 lm32_block_move_inline (operands
[0], operands
[1], INTVAL (operands
[2]),
874 INTVAL (operands
[3]));
880 /* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol
881 isn't protected by a PIC unspec. */
883 nonpic_symbol_mentioned_p (rtx x
)
888 if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == LABEL_REF
889 || GET_CODE (x
) == PC
)
892 /* We don't want to look into the possible MEM location of a
893 CONST_DOUBLE, since we're not going to use it, in general. */
894 if (GET_CODE (x
) == CONST_DOUBLE
)
897 if (GET_CODE (x
) == UNSPEC
)
900 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
901 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
907 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
908 if (nonpic_symbol_mentioned_p (XVECEXP (x
, i
, j
)))
911 else if (fmt
[i
] == 'e' && nonpic_symbol_mentioned_p (XEXP (x
, i
)))
918 /* Compute a (partial) cost for rtx X. Return true if the complete
919 cost has been computed, and false if subexpressions should be
920 scanned. In either case, *TOTAL contains the cost result. */
923 lm32_rtx_costs (rtx x
, int code
, int outer_code
, int *total
, bool speed
)
925 enum machine_mode mode
= GET_MODE (x
);
928 const int arithmetic_latency
= 1;
929 const int shift_latency
= 1;
930 const int compare_latency
= 2;
931 const int multiply_latency
= 3;
932 const int load_latency
= 3;
933 const int libcall_size_cost
= 5;
935 /* Determine if we can handle the given mode size in a single instruction. */
936 small_mode
= (mode
== QImode
) || (mode
== HImode
) || (mode
== SImode
);
949 *total
= COSTS_N_INSNS (LM32_NUM_REGS (mode
));
952 COSTS_N_INSNS (arithmetic_latency
+ (LM32_NUM_REGS (mode
) - 1));
959 *total
= COSTS_N_INSNS (1);
961 *total
= COSTS_N_INSNS (compare_latency
);
965 /* FIXME. Guessing here. */
966 *total
= COSTS_N_INSNS (LM32_NUM_REGS (mode
) * (2 + 3) / 2);
973 if (TARGET_BARREL_SHIFT_ENABLED
&& small_mode
)
976 *total
= COSTS_N_INSNS (1);
978 *total
= COSTS_N_INSNS (shift_latency
);
980 else if (TARGET_BARREL_SHIFT_ENABLED
)
982 /* FIXME: Guessing here. */
983 *total
= COSTS_N_INSNS (LM32_NUM_REGS (mode
) * 4);
985 else if (small_mode
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
987 *total
= COSTS_N_INSNS (INTVAL (XEXP (x
, 1)));
993 *total
= COSTS_N_INSNS (libcall_size_cost
);
995 *total
= COSTS_N_INSNS (100);
1000 if (TARGET_MULTIPLY_ENABLED
&& small_mode
)
1003 *total
= COSTS_N_INSNS (1);
1005 *total
= COSTS_N_INSNS (multiply_latency
);
1011 *total
= COSTS_N_INSNS (libcall_size_cost
);
1013 *total
= COSTS_N_INSNS (100);
1021 if (TARGET_DIVIDE_ENABLED
&& small_mode
)
1024 *total
= COSTS_N_INSNS (1);
1027 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1030 unsigned HOST_WIDE_INT i
= INTVAL (XEXP (x
, 1));
1037 if (IN_RANGE (i
, 0, 65536))
1038 *total
= COSTS_N_INSNS (1 + 1 + cycles
);
1040 *total
= COSTS_N_INSNS (2 + 1 + cycles
);
1043 else if (GET_CODE (XEXP (x
, 1)) == REG
)
1045 *total
= COSTS_N_INSNS (1 + GET_MODE_SIZE (mode
) / 2);
1050 *total
= COSTS_N_INSNS (1 + GET_MODE_SIZE (mode
) / 2);
1059 *total
= COSTS_N_INSNS (libcall_size_cost
);
1061 *total
= COSTS_N_INSNS (100);
1068 *total
= COSTS_N_INSNS (1);
1070 *total
= COSTS_N_INSNS (arithmetic_latency
);
1074 if (MEM_P (XEXP (x
, 0)))
1075 *total
= COSTS_N_INSNS (0);
1076 else if (small_mode
)
1079 *total
= COSTS_N_INSNS (1);
1081 *total
= COSTS_N_INSNS (arithmetic_latency
);
1084 *total
= COSTS_N_INSNS (LM32_NUM_REGS (mode
) / 2);
1093 *total
= COSTS_N_INSNS (0);
1104 if (satisfies_constraint_L (x
))
1105 *total
= COSTS_N_INSNS (0);
1107 *total
= COSTS_N_INSNS (2);
1114 if (satisfies_constraint_K (x
))
1115 *total
= COSTS_N_INSNS (0);
1117 *total
= COSTS_N_INSNS (2);
1121 if (TARGET_MULTIPLY_ENABLED
)
1123 if (satisfies_constraint_K (x
))
1124 *total
= COSTS_N_INSNS (0);
1126 *total
= COSTS_N_INSNS (2);
1132 if (satisfies_constraint_K (x
))
1133 *total
= COSTS_N_INSNS (1);
1135 *total
= COSTS_N_INSNS (2);
1146 *total
= COSTS_N_INSNS (0);
1153 *total
= COSTS_N_INSNS (0);
1162 *total
= COSTS_N_INSNS (2);
1166 *total
= COSTS_N_INSNS (1);
1171 *total
= COSTS_N_INSNS (1);
1173 *total
= COSTS_N_INSNS (load_latency
);
1181 /* Implemenent TARGET_CAN_ELIMINATE. */
1184 lm32_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
1186 return (to
== STACK_POINTER_REGNUM
&& frame_pointer_needed
) ? false : true;
1189 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
1192 lm32_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx x
, bool strict
)
1195 if (strict
&& REG_P (x
) && STRICT_REG_OK_FOR_BASE_P (x
))
1197 if (!strict
&& REG_P (x
) && NONSTRICT_REG_OK_FOR_BASE_P (x
))
1201 if (GET_CODE (x
) == PLUS
1202 && REG_P (XEXP (x
, 0))
1203 && ((strict
&& STRICT_REG_OK_FOR_BASE_P (XEXP (x
, 0)))
1204 || (!strict
&& NONSTRICT_REG_OK_FOR_BASE_P (XEXP (x
, 0))))
1205 && GET_CODE (XEXP (x
, 1)) == CONST_INT
1206 && satisfies_constraint_K (XEXP ((x
), 1)))
1210 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
1216 /* Check a move is not memory to memory. */
1219 lm32_move_ok (enum machine_mode mode
, rtx operands
[2]) {
1220 if (memory_operand (operands
[0], mode
))
1221 return register_or_zero_operand (operands
[1], mode
);
1225 /* Implement LEGITIMATE_CONSTANT_P. */
1228 lm32_legitimate_constant_p (rtx x
)
1230 /* 32-bit addresses require multiple instructions. */
1231 if (!flag_pic
&& reloc_operand (x
, GET_MODE (x
)))