]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/m32r/m32r.c
2014-10-16 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / config / m32r / m32r.c
CommitLineData
aea2fd96 1/* Subroutines used for code generation on the Renesas M32R cpu.
3aea1f79 2 Copyright (C) 1996-2014 Free Software Foundation, Inc.
d868a170 3
aea2fd96 4 This file is part of GCC.
d868a170 5
aea2fd96 6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published
038d1e19 8 by the Free Software Foundation; either version 3, or (at your
aea2fd96 9 option) any later version.
d868a170 10
aea2fd96 11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
d868a170 15
aea2fd96 16 You should have received a copy of the GNU General Public License
038d1e19 17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
d868a170 19
d868a170 20#include "config.h"
7dbe3569 21#include "system.h"
805e22b2 22#include "coretypes.h"
23#include "tm.h"
d868a170 24#include "tree.h"
9ed99284 25#include "stor-layout.h"
26#include "varasm.h"
27#include "stringpool.h"
28#include "calls.h"
d868a170 29#include "rtl.h"
30#include "regs.h"
31#include "hard-reg-set.h"
d868a170 32#include "insn-config.h"
33#include "conditions.h"
d868a170 34#include "output.h"
b5369b7d 35#include "dbxout.h"
d868a170 36#include "insn-attr.h"
37#include "flags.h"
38#include "expr.h"
a3020f2f 39#include "hashtab.h"
40#include "hash-set.h"
41#include "vec.h"
42#include "machmode.h"
43#include "input.h"
4faf81b8 44#include "function.h"
d868a170 45#include "recog.h"
0b205f4c 46#include "diagnostic-core.h"
03033f8f 47#include "ggc.h"
ef51d1e3 48#include "df.h"
79e2a0ca 49#include "tm_p.h"
a767736d 50#include "target.h"
51#include "target-def.h"
bd9c4764 52#include "tm-constrs.h"
fba5dd52 53#include "opts.h"
f7715905 54#include "builtins.h"
d868a170 55
d868a170 56/* Array of valid operand punctuation characters. */
8e8a63d1 57static char m32r_punct_chars[256];
d868a170 58
5c5d0ae9 59/* Machine-specific symbol_ref flags. */
60#define SYMBOL_FLAG_MODEL_SHIFT SYMBOL_FLAG_MACH_DEP_SHIFT
61#define SYMBOL_REF_MODEL(X) \
62 ((enum m32r_model) ((SYMBOL_REF_FLAGS (X) >> SYMBOL_FLAG_MODEL_SHIFT) & 3))
63
64/* For string literals, etc. */
65#define LIT_NAME_P(NAME) ((NAME)[0] == '*' && (NAME)[1] == '.')
66
868d8e32 67/* Forward declaration. */
4c834714 68static void m32r_option_override (void);
0792f2cf 69static void init_reg_tables (void);
70static void block_move_call (rtx, rtx, rtx);
71static int m32r_is_insn (rtx);
bb10104e 72static bool m32r_legitimate_address_p (enum machine_mode, rtx, bool);
41e3a0c7 73static rtx m32r_legitimize_address (rtx, rtx, enum machine_mode);
4e27ffd0 74static bool m32r_mode_dependent_address_p (const_rtx, addr_space_t);
0792f2cf 75static tree m32r_handle_model_attribute (tree *, tree, tree, int, bool *);
8e8a63d1 76static void m32r_print_operand (FILE *, rtx, int);
77static void m32r_print_operand_address (FILE *, rtx);
78static bool m32r_print_operand_punct_valid_p (unsigned char code);
0792f2cf 79static void m32r_output_function_prologue (FILE *, HOST_WIDE_INT);
80static void m32r_output_function_epilogue (FILE *, HOST_WIDE_INT);
81
82static void m32r_file_start (void);
83
18282db0 84static int m32r_adjust_priority (rtx_insn *, int);
0792f2cf 85static int m32r_issue_rate (void);
86
87static void m32r_encode_section_info (tree, rtx, int);
a9f1838b 88static bool m32r_in_small_data_p (const_tree);
fb80456a 89static bool m32r_return_in_memory (const_tree, const_tree);
fb97ed3e 90static rtx m32r_function_value (const_tree, const_tree, bool);
91static rtx m32r_libcall_value (enum machine_mode, const_rtx);
92static bool m32r_function_value_regno_p (const unsigned int);
39cba157 93static void m32r_setup_incoming_varargs (cumulative_args_t, enum machine_mode,
efc813ec 94 tree, int *, int);
0792f2cf 95static void init_idents (void);
20d892d1 96static bool m32r_rtx_costs (rtx, int, int, int, int *, bool speed);
5e5dc6b5 97static int m32r_memory_move_cost (enum machine_mode, reg_class_t, bool);
39cba157 98static bool m32r_pass_by_reference (cumulative_args_t, enum machine_mode,
fb80456a 99 const_tree, bool);
39cba157 100static int m32r_arg_partial_bytes (cumulative_args_t, enum machine_mode,
f054eb3c 101 tree, bool);
39cba157 102static rtx m32r_function_arg (cumulative_args_t, enum machine_mode,
1bd483c2 103 const_tree, bool);
39cba157 104static void m32r_function_arg_advance (cumulative_args_t, enum machine_mode,
1bd483c2 105 const_tree, bool);
cd90919d 106static bool m32r_can_eliminate (const int, const int);
b2d7ede1 107static void m32r_conditional_register_usage (void);
06b77609 108static void m32r_trampoline_init (rtx, tree, rtx);
ca316360 109static bool m32r_legitimate_constant_p (enum machine_mode, rtx);
a767736d 110\f
ef51d1e3 111/* M32R specific attributes. */
112
113static const struct attribute_spec m32r_attribute_table[] =
114{
ac86af5d 115 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
116 affects_type_identity } */
117 { "interrupt", 0, 0, true, false, false, NULL, false },
118 { "model", 1, 1, true, false, false, m32r_handle_model_attribute,
119 false },
120 { NULL, 0, 0, false, false, false, NULL, false }
ef51d1e3 121};
122\f
a767736d 123/* Initialize the GCC target structure. */
aea2fd96 124#undef TARGET_ATTRIBUTE_TABLE
e3c541f0 125#define TARGET_ATTRIBUTE_TABLE m32r_attribute_table
868d8e32 126
bb10104e 127#undef TARGET_LEGITIMATE_ADDRESS_P
128#define TARGET_LEGITIMATE_ADDRESS_P m32r_legitimate_address_p
41e3a0c7 129#undef TARGET_LEGITIMIZE_ADDRESS
130#define TARGET_LEGITIMIZE_ADDRESS m32r_legitimize_address
8c9a773b 131#undef TARGET_MODE_DEPENDENT_ADDRESS_P
132#define TARGET_MODE_DEPENDENT_ADDRESS_P m32r_mode_dependent_address_p
41e3a0c7 133
aea2fd96 134#undef TARGET_ASM_ALIGNED_HI_OP
58356836 135#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
aea2fd96 136#undef TARGET_ASM_ALIGNED_SI_OP
58356836 137#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
138
8e8a63d1 139#undef TARGET_PRINT_OPERAND
140#define TARGET_PRINT_OPERAND m32r_print_operand
141#undef TARGET_PRINT_OPERAND_ADDRESS
142#define TARGET_PRINT_OPERAND_ADDRESS m32r_print_operand_address
143#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
144#define TARGET_PRINT_OPERAND_PUNCT_VALID_P m32r_print_operand_punct_valid_p
145
aea2fd96 146#undef TARGET_ASM_FUNCTION_PROLOGUE
17d9b0c3 147#define TARGET_ASM_FUNCTION_PROLOGUE m32r_output_function_prologue
aea2fd96 148#undef TARGET_ASM_FUNCTION_EPILOGUE
17d9b0c3 149#define TARGET_ASM_FUNCTION_EPILOGUE m32r_output_function_epilogue
150
aea2fd96 151#undef TARGET_ASM_FILE_START
92c473b8 152#define TARGET_ASM_FILE_START m32r_file_start
153
aea2fd96 154#undef TARGET_SCHED_ADJUST_PRIORITY
747af5e7 155#define TARGET_SCHED_ADJUST_PRIORITY m32r_adjust_priority
aea2fd96 156#undef TARGET_SCHED_ISSUE_RATE
747af5e7 157#define TARGET_SCHED_ISSUE_RATE m32r_issue_rate
747af5e7 158
4c834714 159#undef TARGET_OPTION_OVERRIDE
160#define TARGET_OPTION_OVERRIDE m32r_option_override
d21dcfd4 161
aea2fd96 162#undef TARGET_ENCODE_SECTION_INFO
7811991d 163#define TARGET_ENCODE_SECTION_INFO m32r_encode_section_info
aea2fd96 164#undef TARGET_IN_SMALL_DATA_P
5c5d0ae9 165#define TARGET_IN_SMALL_DATA_P m32r_in_small_data_p
7811991d 166
5e5dc6b5 167
09c20b62 168#undef TARGET_MEMORY_MOVE_COST
169#define TARGET_MEMORY_MOVE_COST m32r_memory_move_cost
aea2fd96 170#undef TARGET_RTX_COSTS
fab7adbf 171#define TARGET_RTX_COSTS m32r_rtx_costs
aea2fd96 172#undef TARGET_ADDRESS_COST
d9c5e5f4 173#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
fab7adbf 174
efc813ec 175#undef TARGET_PROMOTE_PROTOTYPES
fb80456a 176#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
efc813ec 177#undef TARGET_RETURN_IN_MEMORY
178#define TARGET_RETURN_IN_MEMORY m32r_return_in_memory
fb97ed3e 179
180#undef TARGET_FUNCTION_VALUE
181#define TARGET_FUNCTION_VALUE m32r_function_value
182#undef TARGET_LIBCALL_VALUE
183#define TARGET_LIBCALL_VALUE m32r_libcall_value
184#undef TARGET_FUNCTION_VALUE_REGNO_P
185#define TARGET_FUNCTION_VALUE_REGNO_P m32r_function_value_regno_p
186
efc813ec 187#undef TARGET_SETUP_INCOMING_VARARGS
188#define TARGET_SETUP_INCOMING_VARARGS m32r_setup_incoming_varargs
0336f0f0 189#undef TARGET_MUST_PASS_IN_STACK
190#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
b981d932 191#undef TARGET_PASS_BY_REFERENCE
192#define TARGET_PASS_BY_REFERENCE m32r_pass_by_reference
f054eb3c 193#undef TARGET_ARG_PARTIAL_BYTES
194#define TARGET_ARG_PARTIAL_BYTES m32r_arg_partial_bytes
1bd483c2 195#undef TARGET_FUNCTION_ARG
196#define TARGET_FUNCTION_ARG m32r_function_arg
197#undef TARGET_FUNCTION_ARG_ADVANCE
198#define TARGET_FUNCTION_ARG_ADVANCE m32r_function_arg_advance
0336f0f0 199
cd90919d 200#undef TARGET_CAN_ELIMINATE
201#define TARGET_CAN_ELIMINATE m32r_can_eliminate
202
b2d7ede1 203#undef TARGET_CONDITIONAL_REGISTER_USAGE
204#define TARGET_CONDITIONAL_REGISTER_USAGE m32r_conditional_register_usage
205
06b77609 206#undef TARGET_TRAMPOLINE_INIT
207#define TARGET_TRAMPOLINE_INIT m32r_trampoline_init
208
ca316360 209#undef TARGET_LEGITIMATE_CONSTANT_P
210#define TARGET_LEGITIMATE_CONSTANT_P m32r_legitimate_constant_p
211
57e4bbfb 212struct gcc_target targetm = TARGET_INITIALIZER;
a767736d 213\f
4c834714 214/* Called by m32r_option_override to initialize various things. */
d868a170 215
216void
aea2fd96 217m32r_init (void)
d868a170 218{
219 init_reg_tables ();
220
8e8a63d1 221 /* Initialize array for TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
d868a170 222 memset (m32r_punct_chars, 0, sizeof (m32r_punct_chars));
223 m32r_punct_chars['#'] = 1;
224 m32r_punct_chars['@'] = 1; /* ??? no longer used */
225
226 /* Provide default value if not specified. */
13a54dd9 227 if (!global_options_set.x_g_switch_value)
d868a170 228 g_switch_value = SDATA_DEFAULT_SIZE;
d868a170 229}
230
4c834714 231static void
232m32r_option_override (void)
233{
234 /* These need to be done at start up.
235 It's convenient to do them here. */
236 m32r_init ();
237 SUBTARGET_OVERRIDE_OPTIONS;
238}
239
d868a170 240/* Vectors to keep interesting information about registers where it can easily
241 be got. We use to use the actual mode value as the bit number, but there
242 is (or may be) more than 32 modes now. Instead we use two tables: one
243 indexed by hard register number, and one indexed by mode. */
244
245/* The purpose of m32r_mode_class is to shrink the range of modes so that
c910419d 246 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
d868a170 247 mapped into one m32r_mode_class mode. */
248
868d8e32 249enum m32r_mode_class
250{
d868a170 251 C_MODE,
252 S_MODE, D_MODE, T_MODE, O_MODE,
947391dc 253 SF_MODE, DF_MODE, TF_MODE, OF_MODE, A_MODE
d868a170 254};
255
256/* Modes for condition codes. */
257#define C_MODES (1 << (int) C_MODE)
258
259/* Modes for single-word and smaller quantities. */
260#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
261
262/* Modes for double-word and smaller quantities. */
263#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
264
265/* Modes for quad-word and smaller quantities. */
266#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
267
947391dc 268/* Modes for accumulators. */
269#define A_MODES (1 << (int) A_MODE)
868d8e32 270
d868a170 271/* Value is 1 if register/mode pair is acceptable on arc. */
272
c8834c5f 273const unsigned int m32r_hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] =
868d8e32 274{
d868a170 275 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
276 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, S_MODES, S_MODES, S_MODES,
6f9235e4 277 S_MODES, C_MODES, A_MODES, A_MODES
d868a170 278};
279
280unsigned int m32r_mode_class [NUM_MACHINE_MODES];
281
282enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
283
284static void
aea2fd96 285init_reg_tables (void)
d868a170 286{
287 int i;
288
289 for (i = 0; i < NUM_MACHINE_MODES; i++)
290 {
92e46ab1 291 enum machine_mode m = (enum machine_mode) i;
292
293 switch (GET_MODE_CLASS (m))
d868a170 294 {
295 case MODE_INT:
296 case MODE_PARTIAL_INT:
297 case MODE_COMPLEX_INT:
92e46ab1 298 if (GET_MODE_SIZE (m) <= 4)
d868a170 299 m32r_mode_class[i] = 1 << (int) S_MODE;
92e46ab1 300 else if (GET_MODE_SIZE (m) == 8)
d868a170 301 m32r_mode_class[i] = 1 << (int) D_MODE;
92e46ab1 302 else if (GET_MODE_SIZE (m) == 16)
d868a170 303 m32r_mode_class[i] = 1 << (int) T_MODE;
92e46ab1 304 else if (GET_MODE_SIZE (m) == 32)
d868a170 305 m32r_mode_class[i] = 1 << (int) O_MODE;
58f4ce52 306 else
d868a170 307 m32r_mode_class[i] = 0;
308 break;
309 case MODE_FLOAT:
310 case MODE_COMPLEX_FLOAT:
92e46ab1 311 if (GET_MODE_SIZE (m) <= 4)
d868a170 312 m32r_mode_class[i] = 1 << (int) SF_MODE;
92e46ab1 313 else if (GET_MODE_SIZE (m) == 8)
d868a170 314 m32r_mode_class[i] = 1 << (int) DF_MODE;
92e46ab1 315 else if (GET_MODE_SIZE (m) == 16)
d868a170 316 m32r_mode_class[i] = 1 << (int) TF_MODE;
92e46ab1 317 else if (GET_MODE_SIZE (m) == 32)
d868a170 318 m32r_mode_class[i] = 1 << (int) OF_MODE;
58f4ce52 319 else
d868a170 320 m32r_mode_class[i] = 0;
321 break;
322 case MODE_CC:
15460c97 323 m32r_mode_class[i] = 1 << (int) C_MODE;
324 break;
d868a170 325 default:
15460c97 326 m32r_mode_class[i] = 0;
d868a170 327 break;
328 }
329 }
330
331 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
332 {
333 if (GPR_P (i))
334 m32r_regno_reg_class[i] = GENERAL_REGS;
335 else if (i == ARG_POINTER_REGNUM)
336 m32r_regno_reg_class[i] = GENERAL_REGS;
337 else
338 m32r_regno_reg_class[i] = NO_REGS;
339 }
340}
341\f
342/* M32R specific attribute support.
343
344 interrupt - for interrupt functions
345
346 model - select code model used to access object
347
348 small: addresses use 24 bits, use bl to make calls
349 medium: addresses use 32 bits, use bl to make calls
350 large: addresses use 32 bits, use seth/add3/jl to make calls
351
aea2fd96 352 Grep for MODEL in m32r.h for more info. */
d868a170 353
d7f038f8 354static tree small_ident1;
355static tree small_ident2;
356static tree medium_ident1;
357static tree medium_ident2;
358static tree large_ident1;
359static tree large_ident2;
360
361static void
aea2fd96 362init_idents (void)
d7f038f8 363{
e3c541f0 364 if (small_ident1 == 0)
d7f038f8 365 {
d7f038f8 366 small_ident1 = get_identifier ("small");
367 small_ident2 = get_identifier ("__small__");
368 medium_ident1 = get_identifier ("medium");
369 medium_ident2 = get_identifier ("__medium__");
370 large_ident1 = get_identifier ("large");
371 large_ident2 = get_identifier ("__large__");
372 }
373}
374
e3c541f0 375/* Handle an "model" attribute; arguments as in
376 struct attribute_spec.handler. */
377static tree
aea2fd96 378m32r_handle_model_attribute (tree *node ATTRIBUTE_UNUSED, tree name,
379 tree args, int flags ATTRIBUTE_UNUSED,
380 bool *no_add_attrs)
d868a170 381{
e3c541f0 382 tree arg;
d868a170 383
e3c541f0 384 init_idents ();
385 arg = TREE_VALUE (args);
386
387 if (arg != small_ident1
388 && arg != small_ident2
389 && arg != medium_ident1
390 && arg != medium_ident2
391 && arg != large_ident1
392 && arg != large_ident2)
393 {
9b2d6d13 394 warning (OPT_Wattributes, "invalid argument of %qs attribute",
e3c541f0 395 IDENTIFIER_POINTER (name));
396 *no_add_attrs = true;
397 }
d868a170 398
e3c541f0 399 return NULL_TREE;
d868a170 400}
d868a170 401\f
d868a170 402/* Encode section information of DECL, which is either a VAR_DECL,
403 FUNCTION_DECL, STRING_CST, CONSTRUCTOR, or ???.
404
405 For the M32R we want to record:
406
407 - whether the object lives in .sdata/.sbss.
d868a170 408 - what code model should be used to access the object
d868a170 409*/
410
7811991d 411static void
aea2fd96 412m32r_encode_section_info (tree decl, rtx rtl, int first)
d868a170 413{
5c5d0ae9 414 int extra_flags = 0;
415 tree model_attr;
416 enum m32r_model model;
d868a170 417
2c129d70 418 default_encode_section_info (decl, rtl, first);
5c5d0ae9 419
420 if (!DECL_P (decl))
41eb471c 421 return;
422
5c5d0ae9 423 model_attr = lookup_attribute ("model", DECL_ATTRIBUTES (decl));
424 if (model_attr)
d868a170 425 {
5c5d0ae9 426 tree id;
d868a170 427
5c5d0ae9 428 init_idents ();
d868a170 429
5c5d0ae9 430 id = TREE_VALUE (TREE_VALUE (model_attr));
d868a170 431
5c5d0ae9 432 if (id == small_ident1 || id == small_ident2)
433 model = M32R_MODEL_SMALL;
434 else if (id == medium_ident1 || id == medium_ident2)
435 model = M32R_MODEL_MEDIUM;
436 else if (id == large_ident1 || id == large_ident2)
437 model = M32R_MODEL_LARGE;
438 else
7afac3c3 439 gcc_unreachable (); /* shouldn't happen */
5c5d0ae9 440 }
441 else
d868a170 442 {
5c5d0ae9 443 if (TARGET_MODEL_SMALL)
444 model = M32R_MODEL_SMALL;
445 else if (TARGET_MODEL_MEDIUM)
446 model = M32R_MODEL_MEDIUM;
447 else if (TARGET_MODEL_LARGE)
448 model = M32R_MODEL_LARGE;
d868a170 449 else
7afac3c3 450 gcc_unreachable (); /* shouldn't happen */
d868a170 451 }
5c5d0ae9 452 extra_flags |= model << SYMBOL_FLAG_MODEL_SHIFT;
d868a170 453
5c5d0ae9 454 if (extra_flags)
2c129d70 455 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= extra_flags;
5c5d0ae9 456}
d7f038f8 457
5c5d0ae9 458/* Only mark the object as being small data area addressable if
459 it hasn't been explicitly marked with a code model.
d7f038f8 460
5c5d0ae9 461 The user can explicitly put an object in the small data area with the
462 section attribute. If the object is in sdata/sbss and marked with a
463 code model do both [put the object in .sdata and mark it as being
464 addressed with a specific code model - don't mark it as being addressed
465 with an SDA reloc though]. This is ok and might be useful at times. If
466 the object doesn't fit the linker will give an error. */
d868a170 467
5c5d0ae9 468static bool
a9f1838b 469m32r_in_small_data_p (const_tree decl)
5c5d0ae9 470{
738a6bda 471 const char *section;
5c5d0ae9 472
473 if (TREE_CODE (decl) != VAR_DECL)
474 return false;
475
476 if (lookup_attribute ("model", DECL_ATTRIBUTES (decl)))
477 return false;
478
479 section = DECL_SECTION_NAME (decl);
480 if (section)
d868a170 481 {
738a6bda 482 if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0)
5c5d0ae9 483 return true;
d868a170 484 }
5c5d0ae9 485 else
486 {
487 if (! TREE_READONLY (decl) && ! TARGET_SDATA_NONE)
488 {
489 int size = int_size_in_bytes (TREE_TYPE (decl));
d868a170 490
13a54dd9 491 if (size > 0 && size <= g_switch_value)
5c5d0ae9 492 return true;
493 }
494 }
7b4a38a6 495
5c5d0ae9 496 return false;
7b4a38a6 497}
498
d868a170 499/* Do anything needed before RTL is emitted for each function. */
500
501void
aea2fd96 502m32r_init_expanders (void)
d868a170 503{
504 /* ??? At one point there was code here. The function is left in
505 to make it easy to experiment. */
506}
507\f
d868a170 508int
aea2fd96 509call_operand (rtx op, enum machine_mode mode)
d868a170 510{
452bfb8b 511 if (!MEM_P (op))
d868a170 512 return 0;
513 op = XEXP (op, 0);
514 return call_address_operand (op, mode);
515}
516
d868a170 517/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
518
519int
aea2fd96 520small_data_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
d868a170 521{
522 if (! TARGET_SDATA_USE)
523 return 0;
524
525 if (GET_CODE (op) == SYMBOL_REF)
5c5d0ae9 526 return SYMBOL_REF_SMALL_P (op);
d868a170 527
528 if (GET_CODE (op) == CONST
529 && GET_CODE (XEXP (op, 0)) == PLUS
530 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
bd9c4764 531 && satisfies_constraint_J (XEXP (XEXP (op, 0), 1)))
5c5d0ae9 532 return SYMBOL_REF_SMALL_P (XEXP (XEXP (op, 0), 0));
d868a170 533
534 return 0;
535}
536
c910419d 537/* Return 1 if OP is a symbol that can use 24-bit addressing. */
d868a170 538
539int
aea2fd96 540addr24_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
d868a170 541{
5c5d0ae9 542 rtx sym;
543
467dc9aa 544 if (flag_pic)
545 return 0;
546
d868a170 547 if (GET_CODE (op) == LABEL_REF)
548 return TARGET_ADDR24;
549
550 if (GET_CODE (op) == SYMBOL_REF)
5c5d0ae9 551 sym = op;
552 else if (GET_CODE (op) == CONST
553 && GET_CODE (XEXP (op, 0)) == PLUS
554 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
bd9c4764 555 && satisfies_constraint_M (XEXP (XEXP (op, 0), 1)))
5c5d0ae9 556 sym = XEXP (XEXP (op, 0), 0);
557 else
558 return 0;
d868a170 559
5c5d0ae9 560 if (SYMBOL_REF_MODEL (sym) == M32R_MODEL_SMALL)
561 return 1;
562
563 if (TARGET_ADDR24
564 && (CONSTANT_POOL_ADDRESS_P (sym)
565 || LIT_NAME_P (XSTR (sym, 0))))
566 return 1;
d868a170 567
568 return 0;
569}
570
c910419d 571/* Return 1 if OP is a symbol that needs 32-bit addressing. */
d868a170 572
573int
aea2fd96 574addr32_operand (rtx op, enum machine_mode mode)
d868a170 575{
5c5d0ae9 576 rtx sym;
577
d868a170 578 if (GET_CODE (op) == LABEL_REF)
579 return TARGET_ADDR32;
580
581 if (GET_CODE (op) == SYMBOL_REF)
5c5d0ae9 582 sym = op;
583 else if (GET_CODE (op) == CONST
584 && GET_CODE (XEXP (op, 0)) == PLUS
585 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
452bfb8b 586 && CONST_INT_P (XEXP (XEXP (op, 0), 1))
467dc9aa 587 && ! flag_pic)
5c5d0ae9 588 sym = XEXP (XEXP (op, 0), 0);
589 else
590 return 0;
d868a170 591
5c5d0ae9 592 return (! addr24_operand (sym, mode)
593 && ! small_data_operand (sym, mode));
d868a170 594}
595
596/* Return 1 if OP is a function that can be called with the `bl' insn. */
597
598int
aea2fd96 599call26_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
d868a170 600{
467dc9aa 601 if (flag_pic)
843505b2 602 return 1;
467dc9aa 603
d868a170 604 if (GET_CODE (op) == SYMBOL_REF)
5c5d0ae9 605 return SYMBOL_REF_MODEL (op) != M32R_MODEL_LARGE;
d868a170 606
607 return TARGET_CALL26;
608}
609
d868a170 610/* Return 1 if OP is a DImode const we want to handle inline.
611 This must match the code in the movdi pattern.
dd41ed59 612 It is used by the 'G' constraint. */
d868a170 613
614int
aea2fd96 615easy_di_const (rtx op)
d868a170 616{
617 rtx high_rtx, low_rtx;
618 HOST_WIDE_INT high, low;
619
620 split_double (op, &high_rtx, &low_rtx);
621 high = INTVAL (high_rtx);
622 low = INTVAL (low_rtx);
c910419d 623 /* Pick constants loadable with 2 16-bit `ldi' insns. */
d868a170 624 if (high >= -128 && high <= 127
625 && low >= -128 && low <= 127)
626 return 1;
627 return 0;
628}
629
630/* Return 1 if OP is a DFmode const we want to handle inline.
631 This must match the code in the movdf pattern.
dd41ed59 632 It is used by the 'H' constraint. */
d868a170 633
634int
aea2fd96 635easy_df_const (rtx op)
d868a170 636{
637 REAL_VALUE_TYPE r;
638 long l[2];
639
640 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
641 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
642 if (l[0] == 0 && l[1] == 0)
643 return 1;
644 if ((l[0] & 0xffff) == 0 && l[1] == 0)
645 return 1;
646 return 0;
647}
648
d868a170 649/* Return 1 if OP is (mem (reg ...)).
650 This is used in insn length calcs. */
651
652int
aea2fd96 653memreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
d868a170 654{
be96c8c6 655 return MEM_P (op) && REG_P (XEXP (op, 0));
d868a170 656}
868d8e32 657
b981d932 658/* Return nonzero if TYPE must be passed by indirect reference. */
daece349 659
b981d932 660static bool
39cba157 661m32r_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
fb80456a 662 enum machine_mode mode, const_tree type,
b981d932 663 bool named ATTRIBUTE_UNUSED)
daece349 664{
b981d932 665 int size;
daece349 666
b981d932 667 if (type)
668 size = int_size_in_bytes (type);
669 else
670 size = GET_MODE_SIZE (mode);
daece349 671
b981d932 672 return (size < 0 || size > 8);
daece349 673}
d868a170 674\f
675/* Comparisons. */
676
d868a170 677/* X and Y are two things to compare using CODE. Emit the compare insn and
868d8e32 678 return the rtx for compare [arg0 of the if_then_else].
679 If need_compare is true then the comparison insn must be generated, rather
dfd1079d 680 than being subsumed into the following branch instruction. */
d868a170 681
682rtx
aea2fd96 683gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
d868a170 684{
aea2fd96 685 enum rtx_code compare_code;
686 enum rtx_code branch_code;
60a061f2 687 rtx cc_reg = gen_rtx_REG (CCmode, CARRY_REGNUM);
6441a98f 688 int must_swap = 0;
d868a170 689
690 switch (code)
691 {
8ec9afef 692 case EQ: compare_code = EQ; branch_code = NE; break;
693 case NE: compare_code = EQ; branch_code = EQ; break;
694 case LT: compare_code = LT; branch_code = NE; break;
695 case LE: compare_code = LT; branch_code = EQ; must_swap = 1; break;
696 case GT: compare_code = LT; branch_code = NE; must_swap = 1; break;
697 case GE: compare_code = LT; branch_code = EQ; break;
d868a170 698 case LTU: compare_code = LTU; branch_code = NE; break;
8ec9afef 699 case LEU: compare_code = LTU; branch_code = EQ; must_swap = 1; break;
700 case GTU: compare_code = LTU; branch_code = NE; must_swap = 1; break;
d868a170 701 case GEU: compare_code = LTU; branch_code = EQ; break;
6441a98f 702
703 default:
7afac3c3 704 gcc_unreachable ();
d868a170 705 }
706
868d8e32 707 if (need_compare)
708 {
709 switch (compare_code)
710 {
711 case EQ:
bd9c4764 712 if (satisfies_constraint_P (y) /* Reg equal to small const. */
868d8e32 713 && y != const0_rtx)
714 {
58f4ce52 715 rtx tmp = gen_reg_rtx (SImode);
716
467cdcb9 717 emit_insn (gen_addsi3 (tmp, x, GEN_INT (-INTVAL (y))));
868d8e32 718 x = tmp;
719 y = const0_rtx;
720 }
aea2fd96 721 else if (CONSTANT_P (y)) /* Reg equal to const. */
868d8e32 722 {
723 rtx tmp = force_reg (GET_MODE (x), y);
724 y = tmp;
725 }
726
aea2fd96 727 if (register_operand (y, SImode) /* Reg equal to reg. */
728 || y == const0_rtx) /* Reg equal to zero. */
868d8e32 729 {
947391dc 730 emit_insn (gen_cmp_eqsi_insn (x, y));
58f4ce52 731
29bb088d 732 return gen_rtx_fmt_ee (code, CCmode, cc_reg, const0_rtx);
868d8e32 733 }
734 break;
58f4ce52 735
868d8e32 736 case LT:
737 if (register_operand (y, SImode)
bd9c4764 738 || satisfies_constraint_P (y))
868d8e32 739 {
aea2fd96 740 rtx tmp = gen_reg_rtx (SImode); /* Reg compared to reg. */
58f4ce52 741
868d8e32 742 switch (code)
743 {
744 case LT:
745 emit_insn (gen_cmp_ltsi_insn (x, y));
746 code = EQ;
747 break;
748 case LE:
749 if (y == const0_rtx)
750 tmp = const1_rtx;
751 else
467cdcb9 752 emit_insn (gen_addsi3 (tmp, y, constm1_rtx));
868d8e32 753 emit_insn (gen_cmp_ltsi_insn (x, tmp));
754 code = EQ;
755 break;
756 case GT:
452bfb8b 757 if (CONST_INT_P (y))
1a83b3ff 758 tmp = gen_rtx_PLUS (SImode, y, const1_rtx);
868d8e32 759 else
467cdcb9 760 emit_insn (gen_addsi3 (tmp, y, constm1_rtx));
868d8e32 761 emit_insn (gen_cmp_ltsi_insn (x, tmp));
762 code = NE;
763 break;
764 case GE:
765 emit_insn (gen_cmp_ltsi_insn (x, y));
766 code = NE;
767 break;
768 default:
7afac3c3 769 gcc_unreachable ();
868d8e32 770 }
58f4ce52 771
29bb088d 772 return gen_rtx_fmt_ee (code, CCmode, cc_reg, const0_rtx);
868d8e32 773 }
774 break;
58f4ce52 775
868d8e32 776 case LTU:
777 if (register_operand (y, SImode)
bd9c4764 778 || satisfies_constraint_P (y))
868d8e32 779 {
aea2fd96 780 rtx tmp = gen_reg_rtx (SImode); /* Reg (unsigned) compared to reg. */
58f4ce52 781
868d8e32 782 switch (code)
783 {
784 case LTU:
785 emit_insn (gen_cmp_ltusi_insn (x, y));
786 code = EQ;
787 break;
788 case LEU:
789 if (y == const0_rtx)
790 tmp = const1_rtx;
791 else
467cdcb9 792 emit_insn (gen_addsi3 (tmp, y, constm1_rtx));
868d8e32 793 emit_insn (gen_cmp_ltusi_insn (x, tmp));
794 code = EQ;
795 break;
796 case GTU:
452bfb8b 797 if (CONST_INT_P (y))
1a83b3ff 798 tmp = gen_rtx_PLUS (SImode, y, const1_rtx);
868d8e32 799 else
467cdcb9 800 emit_insn (gen_addsi3 (tmp, y, constm1_rtx));
868d8e32 801 emit_insn (gen_cmp_ltusi_insn (x, tmp));
802 code = NE;
803 break;
804 case GEU:
805 emit_insn (gen_cmp_ltusi_insn (x, y));
806 code = NE;
807 break;
808 default:
7afac3c3 809 gcc_unreachable ();
868d8e32 810 }
58f4ce52 811
29bb088d 812 return gen_rtx_fmt_ee (code, CCmode, cc_reg, const0_rtx);
868d8e32 813 }
814 break;
815
816 default:
7afac3c3 817 gcc_unreachable ();
868d8e32 818 }
819 }
820 else
d868a170 821 {
aea2fd96 822 /* Reg/reg equal comparison. */
d868a170 823 if (compare_code == EQ
824 && register_operand (y, SImode))
29bb088d 825 return gen_rtx_fmt_ee (code, CCmode, x, y);
58f4ce52 826
aea2fd96 827 /* Reg/zero signed comparison. */
d868a170 828 if ((compare_code == EQ || compare_code == LT)
829 && y == const0_rtx)
29bb088d 830 return gen_rtx_fmt_ee (code, CCmode, x, y);
58f4ce52 831
aea2fd96 832 /* Reg/smallconst equal comparison. */
d868a170 833 if (compare_code == EQ
bd9c4764 834 && satisfies_constraint_P (y))
d868a170 835 {
836 rtx tmp = gen_reg_rtx (SImode);
aea2fd96 837
467cdcb9 838 emit_insn (gen_addsi3 (tmp, x, GEN_INT (-INTVAL (y))));
29bb088d 839 return gen_rtx_fmt_ee (code, CCmode, tmp, const0_rtx);
d868a170 840 }
58f4ce52 841
aea2fd96 842 /* Reg/const equal comparison. */
d868a170 843 if (compare_code == EQ
844 && CONSTANT_P (y))
845 {
846 rtx tmp = force_reg (GET_MODE (x), y);
aea2fd96 847
29bb088d 848 return gen_rtx_fmt_ee (code, CCmode, x, tmp);
d868a170 849 }
850 }
851
8ec9afef 852 if (CONSTANT_P (y))
d868a170 853 {
8ec9afef 854 if (must_swap)
d868a170 855 y = force_reg (GET_MODE (x), y);
8ec9afef 856 else
857 {
4c6c8621 858 int ok_const = reg_or_int16_operand (y, GET_MODE (y));
859
8ec9afef 860 if (! ok_const)
861 y = force_reg (GET_MODE (x), y);
862 }
d868a170 863 }
864
865 switch (compare_code)
866 {
867 case EQ :
8ec9afef 868 emit_insn (gen_cmp_eqsi_insn (must_swap ? y : x, must_swap ? x : y));
d868a170 869 break;
870 case LT :
8ec9afef 871 emit_insn (gen_cmp_ltsi_insn (must_swap ? y : x, must_swap ? x : y));
d868a170 872 break;
873 case LTU :
8ec9afef 874 emit_insn (gen_cmp_ltusi_insn (must_swap ? y : x, must_swap ? x : y));
d868a170 875 break;
6441a98f 876
877 default:
7afac3c3 878 gcc_unreachable ();
d868a170 879 }
880
29bb088d 881 return gen_rtx_fmt_ee (branch_code, VOIDmode, cc_reg, CONST0_RTX (CCmode));
d868a170 882}
74f4459c 883
884bool
885gen_cond_store (enum rtx_code code, rtx op0, rtx op1, rtx op2)
886{
887 enum machine_mode mode = GET_MODE (op0);
888
889 gcc_assert (mode == SImode);
890 switch (code)
891 {
892 case EQ:
893 if (!register_operand (op1, mode))
894 op1 = force_reg (mode, op1);
895
896 if (TARGET_M32RX || TARGET_M32R2)
897 {
898 if (!reg_or_zero_operand (op2, mode))
899 op2 = force_reg (mode, op2);
900
901 emit_insn (gen_seq_insn_m32rx (op0, op1, op2));
902 return true;
903 }
452bfb8b 904 if (CONST_INT_P (op2) && INTVAL (op2) == 0)
74f4459c 905 {
906 emit_insn (gen_seq_zero_insn (op0, op1));
907 return true;
908 }
909
910 if (!reg_or_eq_int16_operand (op2, mode))
911 op2 = force_reg (mode, op2);
912
913 emit_insn (gen_seq_insn (op0, op1, op2));
914 return true;
915
916 case NE:
452bfb8b 917 if (!CONST_INT_P (op2)
74f4459c 918 || (INTVAL (op2) != 0 && satisfies_constraint_K (op2)))
919 {
920 rtx reg;
921
922 if (reload_completed || reload_in_progress)
923 return false;
924
925 reg = gen_reg_rtx (SImode);
926 emit_insn (gen_xorsi3 (reg, op1, op2));
927 op1 = reg;
928
929 if (!register_operand (op1, mode))
930 op1 = force_reg (mode, op1);
931
932 emit_insn (gen_sne_zero_insn (op0, op1));
933 return true;
934 }
935 return false;
936
937 case LT:
938 case GT:
939 if (code == GT)
940 {
941 rtx tmp = op2;
942 op2 = op1;
943 op1 = tmp;
944 code = LT;
945 }
946
947 if (!register_operand (op1, mode))
948 op1 = force_reg (mode, op1);
949
950 if (!reg_or_int16_operand (op2, mode))
951 op2 = force_reg (mode, op2);
952
953 emit_insn (gen_slt_insn (op0, op1, op2));
954 return true;
955
956 case LTU:
957 case GTU:
958 if (code == GTU)
959 {
960 rtx tmp = op2;
961 op2 = op1;
962 op1 = tmp;
963 code = LTU;
964 }
965
966 if (!register_operand (op1, mode))
967 op1 = force_reg (mode, op1);
968
969 if (!reg_or_int16_operand (op2, mode))
970 op2 = force_reg (mode, op2);
971
972 emit_insn (gen_sltu_insn (op0, op1, op2));
973 return true;
974
975 case GE:
976 case GEU:
977 if (!register_operand (op1, mode))
978 op1 = force_reg (mode, op1);
979
980 if (!reg_or_int16_operand (op2, mode))
981 op2 = force_reg (mode, op2);
982
983 if (code == GE)
984 emit_insn (gen_sge_insn (op0, op1, op2));
985 else
986 emit_insn (gen_sgeu_insn (op0, op1, op2));
987 return true;
988
989 case LE:
990 case LEU:
991 if (!register_operand (op1, mode))
992 op1 = force_reg (mode, op1);
993
452bfb8b 994 if (CONST_INT_P (op2))
74f4459c 995 {
996 HOST_WIDE_INT value = INTVAL (op2);
997 if (value >= 2147483647)
998 {
999 emit_move_insn (op0, const1_rtx);
1000 return true;
1001 }
1002
1003 op2 = GEN_INT (value + 1);
1004 if (value < -32768 || value >= 32767)
1005 op2 = force_reg (mode, op2);
1006
1007 if (code == LEU)
1008 emit_insn (gen_sltu_insn (op0, op1, op2));
1009 else
1010 emit_insn (gen_slt_insn (op0, op1, op2));
1011 return true;
1012 }
1013
1014 if (!register_operand (op2, mode))
1015 op2 = force_reg (mode, op2);
1016
1017 if (code == LEU)
1018 emit_insn (gen_sleu_insn (op0, op1, op2));
1019 else
1020 emit_insn (gen_sle_insn (op0, op1, op2));
1021 return true;
1022
1023 default:
1024 gcc_unreachable ();
1025 }
1026}
1027
7dbe3569 1028\f
1029/* Split a 2 word move (DI or DF) into component parts. */
1030
1031rtx
aea2fd96 1032gen_split_move_double (rtx operands[])
7dbe3569 1033{
1034 enum machine_mode mode = GET_MODE (operands[0]);
1035 rtx dest = operands[0];
1036 rtx src = operands[1];
1037 rtx val;
1038
df5991ff 1039 /* We might have (SUBREG (MEM)) here, so just get rid of the
1040 subregs to make this code simpler. It is safe to call
1041 alter_subreg any time after reload. */
1042 if (GET_CODE (dest) == SUBREG)
c6a6cdaa 1043 alter_subreg (&dest, true);
df5991ff 1044 if (GET_CODE (src) == SUBREG)
c6a6cdaa 1045 alter_subreg (&src, true);
df5991ff 1046
7dbe3569 1047 start_sequence ();
452bfb8b 1048 if (REG_P (dest))
7dbe3569 1049 {
df5991ff 1050 int dregno = REGNO (dest);
1051
aea2fd96 1052 /* Reg = reg. */
452bfb8b 1053 if (REG_P (src))
7dbe3569 1054 {
df5991ff 1055 int sregno = REGNO (src);
1056
1057 int reverse = (dregno == sregno + 1);
1058
7dbe3569 1059 /* We normally copy the low-numbered register first. However, if
1060 the first register operand 0 is the same as the second register of
1061 operand 1, we must copy in the opposite order. */
7dbe3569 1062 emit_insn (gen_rtx_SET (VOIDmode,
1063 operand_subword (dest, reverse, TRUE, mode),
1064 operand_subword (src, reverse, TRUE, mode)));
1065
1066 emit_insn (gen_rtx_SET (VOIDmode,
1067 operand_subword (dest, !reverse, TRUE, mode),
1068 operand_subword (src, !reverse, TRUE, mode)));
1069 }
1070
aea2fd96 1071 /* Reg = constant. */
452bfb8b 1072 else if (CONST_INT_P (src) || GET_CODE (src) == CONST_DOUBLE)
7dbe3569 1073 {
1074 rtx words[2];
1075 split_double (src, &words[0], &words[1]);
1076 emit_insn (gen_rtx_SET (VOIDmode,
1077 operand_subword (dest, 0, TRUE, mode),
1078 words[0]));
1079
1080 emit_insn (gen_rtx_SET (VOIDmode,
1081 operand_subword (dest, 1, TRUE, mode),
1082 words[1]));
1083 }
1084
aea2fd96 1085 /* Reg = mem. */
452bfb8b 1086 else if (MEM_P (src))
7dbe3569 1087 {
1088 /* If the high-address word is used in the address, we must load it
1089 last. Otherwise, load it first. */
e513d163 1090 int reverse
1091 = (refers_to_regno_p (dregno, dregno + 1, XEXP (src, 0), 0) != 0);
7dbe3569 1092
1093 /* We used to optimize loads from single registers as
1094
1095 ld r1,r3+; ld r2,r3
1096
1097 if r3 were not used subsequently. However, the REG_NOTES aren't
dfd1079d 1098 propagated correctly by the reload phase, and it can cause bad
7dbe3569 1099 code to be generated. We could still try:
1100
1101 ld r1,r3+; ld r2,r3; addi r3,-4
1102
1103 which saves 2 bytes and doesn't force longword alignment. */
1104 emit_insn (gen_rtx_SET (VOIDmode,
1105 operand_subword (dest, reverse, TRUE, mode),
e513d163 1106 adjust_address (src, SImode,
1107 reverse * UNITS_PER_WORD)));
7dbe3569 1108
1109 emit_insn (gen_rtx_SET (VOIDmode,
1110 operand_subword (dest, !reverse, TRUE, mode),
e513d163 1111 adjust_address (src, SImode,
1112 !reverse * UNITS_PER_WORD)));
7dbe3569 1113 }
7dbe3569 1114 else
7afac3c3 1115 gcc_unreachable ();
7dbe3569 1116 }
1117
aea2fd96 1118 /* Mem = reg. */
7dbe3569 1119 /* We used to optimize loads from single registers as
1120
1121 st r1,r3; st r2,+r3
1122
1123 if r3 were not used subsequently. However, the REG_NOTES aren't
dfd1079d 1124 propagated correctly by the reload phase, and it can cause bad
7dbe3569 1125 code to be generated. We could still try:
1126
1127 st r1,r3; st r2,+r3; addi r3,-4
1128
1129 which saves 2 bytes and doesn't force longword alignment. */
be96c8c6 1130 else if (MEM_P (dest) && REG_P (src))
7dbe3569 1131 {
7dbe3569 1132 emit_insn (gen_rtx_SET (VOIDmode,
e513d163 1133 adjust_address (dest, SImode, 0),
7dbe3569 1134 operand_subword (src, 0, TRUE, mode)));
1135
1136 emit_insn (gen_rtx_SET (VOIDmode,
e513d163 1137 adjust_address (dest, SImode, UNITS_PER_WORD),
7dbe3569 1138 operand_subword (src, 1, TRUE, mode)));
1139 }
1140
1141 else
7afac3c3 1142 gcc_unreachable ();
7dbe3569 1143
31d3e01c 1144 val = get_insns ();
7dbe3569 1145 end_sequence ();
1146 return val;
1147}
1148
d868a170 1149\f
f054eb3c 1150static int
39cba157 1151m32r_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
f054eb3c 1152 tree type, bool named ATTRIBUTE_UNUSED)
d868a170 1153{
39cba157 1154 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1155
f054eb3c 1156 int words;
03033f8f 1157 unsigned int size =
1158 (((mode == BLKmode && type)
1159 ? (unsigned int) int_size_in_bytes (type)
1160 : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
1161 / UNITS_PER_WORD;
d868a170 1162
1163 if (*cum >= M32R_MAX_PARM_REGS)
f054eb3c 1164 words = 0;
d868a170 1165 else if (*cum + size > M32R_MAX_PARM_REGS)
f054eb3c 1166 words = (*cum + size) - M32R_MAX_PARM_REGS;
d868a170 1167 else
f054eb3c 1168 words = 0;
d868a170 1169
f054eb3c 1170 return words * UNITS_PER_WORD;
d868a170 1171}
1172
1bd483c2 1173/* The ROUND_ADVANCE* macros are local to this file. */
1174/* Round SIZE up to a word boundary. */
1175#define ROUND_ADVANCE(SIZE) \
1176 (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1177
1178/* Round arg MODE/TYPE up to the next word boundary. */
1179#define ROUND_ADVANCE_ARG(MODE, TYPE) \
1180 ((MODE) == BLKmode \
1181 ? ROUND_ADVANCE ((unsigned int) int_size_in_bytes (TYPE)) \
1182 : ROUND_ADVANCE ((unsigned int) GET_MODE_SIZE (MODE)))
1183
1184/* Round CUM up to the necessary point for argument MODE/TYPE. */
1185#define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) (CUM)
1186
1187/* Return boolean indicating arg of type TYPE and mode MODE will be passed in
1188 a reg. This includes arguments that have to be passed by reference as the
1189 pointer to them is passed in a reg if one is available (and that is what
1190 we're given).
1191 This macro is only used in this file. */
1192#define PASS_IN_REG_P(CUM, MODE, TYPE) \
1193 (ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) < M32R_MAX_PARM_REGS)
1194
1195/* Determine where to put an argument to a function.
1196 Value is zero to push the argument on the stack,
1197 or a hard register in which to store the argument.
1198
1199 MODE is the argument's machine mode.
1200 TYPE is the data type of the argument (as a tree).
1201 This is null for libcalls where that information may
1202 not be available.
1203 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1204 the preceding args and about the function being called.
1205 NAMED is nonzero if this argument is a named parameter
1206 (otherwise it is an extra parameter matching an ellipsis). */
1207/* On the M32R the first M32R_MAX_PARM_REGS args are normally in registers
1208 and the rest are pushed. */
1209
1210static rtx
39cba157 1211m32r_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
09c20b62 1212 const_tree type ATTRIBUTE_UNUSED,
1213 bool named ATTRIBUTE_UNUSED)
1bd483c2 1214{
39cba157 1215 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1216
1bd483c2 1217 return (PASS_IN_REG_P (*cum, mode, type)
1218 ? gen_rtx_REG (mode, ROUND_ADVANCE_CUM (*cum, mode, type))
1219 : NULL_RTX);
1220}
1221
1222/* Update the data in CUM to advance over an argument
1223 of mode MODE and data type TYPE.
1224 (TYPE is null for libcalls where that information may not be available.) */
1225
1226static void
39cba157 1227m32r_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1bd483c2 1228 const_tree type, bool named ATTRIBUTE_UNUSED)
1229{
39cba157 1230 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1231
1bd483c2 1232 *cum = (ROUND_ADVANCE_CUM (*cum, mode, type)
1233 + ROUND_ADVANCE_ARG (mode, type));
1234}
1235
efc813ec 1236/* Worker function for TARGET_RETURN_IN_MEMORY. */
1237
1238static bool
fb80456a 1239m32r_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
efc813ec 1240{
39cba157 1241 cumulative_args_t dummy = pack_cumulative_args (NULL);
1242
1243 return m32r_pass_by_reference (dummy, TYPE_MODE (type), type, false);
efc813ec 1244}
1245
fb97ed3e 1246/* Worker function for TARGET_FUNCTION_VALUE. */
1247
1248static rtx
1249m32r_function_value (const_tree valtype,
1250 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1251 bool outgoing ATTRIBUTE_UNUSED)
1252{
1253 return gen_rtx_REG (TYPE_MODE (valtype), 0);
1254}
1255
1256/* Worker function for TARGET_LIBCALL_VALUE. */
1257
1258static rtx
1259m32r_libcall_value (enum machine_mode mode,
1260 const_rtx fun ATTRIBUTE_UNUSED)
1261{
1262 return gen_rtx_REG (mode, 0);
1263}
1264
1265/* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1266
1267 ??? What about r1 in DI/DF values. */
1268
1269static bool
1270m32r_function_value_regno_p (const unsigned int regno)
1271{
1272 return (regno == 0);
1273}
1274
d868a170 1275/* Do any needed setup for a variadic function. For the M32R, we must
1276 create a register parameter block, and then copy any anonymous arguments
1277 in registers to memory.
1278
1279 CUM has not been updated for the last named argument which has type TYPE
1280 and mode MODE, and we rely on this fact. */
1281
efc813ec 1282static void
39cba157 1283m32r_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
aea2fd96 1284 tree type, int *pretend_size, int no_rtl)
d868a170 1285{
1286 int first_anon_arg;
1287
1288 if (no_rtl)
1289 return;
1290
1291 /* All BLKmode values are passed by reference. */
7afac3c3 1292 gcc_assert (mode != BLKmode);
d868a170 1293
39cba157 1294 first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum), mode, type)
7ccc713a 1295 + ROUND_ADVANCE_ARG (mode, type));
d868a170 1296
1297 if (first_anon_arg < M32R_MAX_PARM_REGS)
1298 {
1299 /* Note that first_reg_offset < M32R_MAX_PARM_REGS. */
1300 int first_reg_offset = first_anon_arg;
1301 /* Size in words to "pretend" allocate. */
1302 int size = M32R_MAX_PARM_REGS - first_reg_offset;
1303 rtx regblock;
1304
58f4ce52 1305 regblock = gen_frame_mem (BLKmode,
29c05e22 1306 plus_constant (Pmode, arg_pointer_rtx,
58f4ce52 1307 FIRST_PARM_OFFSET (0)));
ab6ab77e 1308 set_mem_alias_set (regblock, get_varargs_alias_set ());
530178a9 1309 move_block_from_reg (first_reg_offset, regblock, size);
d868a170 1310
1311 *pretend_size = (size * UNITS_PER_WORD);
1312 }
1313}
acfbd054 1314
947391dc 1315\f
4a655456 1316/* Return true if INSN is real instruction bearing insn. */
947391dc 1317
4a655456 1318static int
aea2fd96 1319m32r_is_insn (rtx insn)
4a655456 1320{
f5417e32 1321 return (NONDEBUG_INSN_P (insn)
4a655456 1322 && GET_CODE (PATTERN (insn)) != USE
77985f1a 1323 && GET_CODE (PATTERN (insn)) != CLOBBER);
4a655456 1324}
1325
1326/* Increase the priority of long instructions so that the
1327 short instructions are scheduled ahead of the long ones. */
947391dc 1328
747af5e7 1329static int
18282db0 1330m32r_adjust_priority (rtx_insn *insn, int priority)
947391dc 1331{
4a655456 1332 if (m32r_is_insn (insn)
1333 && get_attr_insn_size (insn) != INSN_SIZE_SHORT)
1334 priority <<= 3;
947391dc 1335
1336 return priority;
1337}
1338
1339\f
747af5e7 1340/* Indicate how many instructions can be issued at the same time.
1341 This is sort of a lie. The m32r can issue only 1 long insn at
1342 once, but it can issue 2 short insns. The default therefore is
1343 set at 2, but this can be overridden by the command line option
aea2fd96 1344 -missue-rate=1. */
1345
747af5e7 1346static int
aea2fd96 1347m32r_issue_rate (void)
747af5e7 1348{
1349 return ((TARGET_LOW_ISSUE_RATE) ? 1 : 2);
947391dc 1350}
947391dc 1351\f
d868a170 1352/* Cost functions. */
218e3e4e 1353/* Memory is 3 times as expensive as registers.
5e5dc6b5 1354 ??? Is that the right way to look at it? */
1355
1356static int
1357m32r_memory_move_cost (enum machine_mode mode,
1358 reg_class_t rclass ATTRIBUTE_UNUSED,
1359 bool in ATTRIBUTE_UNUSED)
1360{
1361 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
1362 return 6;
1363 else
1364 return 12;
1365}
1366
fab7adbf 1367static bool
20d892d1 1368m32r_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
1369 int opno ATTRIBUTE_UNUSED, int *total,
f529eb25 1370 bool speed ATTRIBUTE_UNUSED)
fab7adbf 1371{
1372 switch (code)
1373 {
1374 /* Small integers are as cheap as registers. 4 byte values can be
1375 fetched as immediate constants - let's give that the cost of an
1376 extra insn. */
1377 case CONST_INT:
1378 if (INT16_P (INTVAL (x)))
1379 {
1380 *total = 0;
1381 return true;
1382 }
8e262b5e 1383 /* FALLTHRU */
fab7adbf 1384
1385 case CONST:
1386 case LABEL_REF:
1387 case SYMBOL_REF:
1388 *total = COSTS_N_INSNS (1);
1389 return true;
1390
1391 case CONST_DOUBLE:
1392 {
1393 rtx high, low;
aea2fd96 1394
fab7adbf 1395 split_double (x, &high, &low);
1396 *total = COSTS_N_INSNS (!INT16_P (INTVAL (high))
1397 + !INT16_P (INTVAL (low)));
1398 return true;
1399 }
1400
1401 case MULT:
1402 *total = COSTS_N_INSNS (3);
1403 return true;
1404
1405 case DIV:
1406 case UDIV:
1407 case MOD:
1408 case UMOD:
1409 *total = COSTS_N_INSNS (10);
1410 return true;
1411
1412 default:
1413 return false;
1414 }
1415}
d868a170 1416\f
1417/* Type of function DECL.
1418
1419 The result is cached. To reset the cache at the end of a function,
1420 call with DECL = NULL_TREE. */
1421
1422enum m32r_function_type
aea2fd96 1423m32r_compute_function_type (tree decl)
d868a170 1424{
1425 /* Cached value. */
1426 static enum m32r_function_type fn_type = M32R_FUNCTION_UNKNOWN;
1427 /* Last function we were called for. */
1428 static tree last_fn = NULL_TREE;
1429
1430 /* Resetting the cached value? */
1431 if (decl == NULL_TREE)
1432 {
1433 fn_type = M32R_FUNCTION_UNKNOWN;
1434 last_fn = NULL_TREE;
1435 return fn_type;
1436 }
1437
1438 if (decl == last_fn && fn_type != M32R_FUNCTION_UNKNOWN)
1439 return fn_type;
1440
1441 /* Compute function type. */
e3c541f0 1442 fn_type = (lookup_attribute ("interrupt", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE
d868a170 1443 ? M32R_FUNCTION_INTERRUPT
1444 : M32R_FUNCTION_NORMAL);
1445
1446 last_fn = decl;
1447 return fn_type;
1448}
1449\f/* Function prologue/epilogue handlers. */
1450
1451/* M32R stack frames look like:
1452
1453 Before call After call
1454 +-----------------------+ +-----------------------+
1455 | | | |
1456 high | local variables, | | local variables, |
1457 mem | reg save area, etc. | | reg save area, etc. |
1458 | | | |
1459 +-----------------------+ +-----------------------+
1460 | | | |
1461 | arguments on stack. | | arguments on stack. |
1462 | | | |
1463 SP+0->+-----------------------+ +-----------------------+
1464 | reg parm save area, |
58f4ce52 1465 | only created for |
1466 | variable argument |
1467 | functions |
d868a170 1468 +-----------------------+
1469 | previous frame ptr |
58f4ce52 1470 +-----------------------+
1471 | |
1472 | register save area |
1473 | |
d868a170 1474 +-----------------------+
58f4ce52 1475 | return address |
1476 +-----------------------+
1477 | |
1478 | local variables |
1479 | |
1480 +-----------------------+
1481 | |
1482 | alloca allocations |
1483 | |
1484 +-----------------------+
1485 | |
1486 low | arguments on stack |
1487 memory | |
1488 SP+0->+-----------------------+
d868a170 1489
1490Notes:
14911) The "reg parm save area" does not exist for non variable argument fns.
14922) The "reg parm save area" can be eliminated completely if we saved regs
1493 containing anonymous args separately but that complicates things too
1494 much (so it's not done).
14953) The return address is saved after the register save area so as to have as
aea2fd96 1496 many insns as possible between the restoration of `lr' and the `jmp lr'. */
d868a170 1497
1498/* Structure to be filled in by m32r_compute_frame_size with register
1499 save masks, and offsets for the current function. */
1500struct m32r_frame_info
1501{
aea2fd96 1502 unsigned int total_size; /* # bytes that the entire frame takes up. */
1503 unsigned int extra_size; /* # bytes of extra stuff. */
1504 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
1505 unsigned int args_size; /* # bytes that outgoing arguments take up. */
1506 unsigned int reg_size; /* # bytes needed to store regs. */
1507 unsigned int var_size; /* # bytes that variables take up. */
1508 unsigned int gmask; /* Mask of saved gp registers. */
1509 unsigned int save_fp; /* Nonzero if fp must be saved. */
1510 unsigned int save_lr; /* Nonzero if lr (return addr) must be saved. */
1511 int initialized; /* Nonzero if frame size already calculated. */
d868a170 1512};
1513
1514/* Current frame information calculated by m32r_compute_frame_size. */
1515static struct m32r_frame_info current_frame_info;
1516
1517/* Zero structure to initialize current_frame_info. */
1518static struct m32r_frame_info zero_frame_info;
1519
1520#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
aea2fd96 1521#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
d868a170 1522
1523/* Tell prologue and epilogue if register REGNO should be saved / restored.
1524 The return address and frame pointer are treated separately.
1525 Don't consider them here. */
1526#define MUST_SAVE_REGISTER(regno, interrupt_p) \
bca30b06 1527 ((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
3072d30e 1528 && (df_regs_ever_live_p (regno) && (!call_really_used_regs[regno] || interrupt_p)))
d868a170 1529
3072d30e 1530#define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM))
18d50ae6 1531#define MUST_SAVE_RETURN_ADDR (df_regs_ever_live_p (RETURN_ADDR_REGNUM) || crtl->profile)
d868a170 1532
aea2fd96 1533#define SHORT_INSN_SIZE 2 /* Size of small instructions. */
1534#define LONG_INSN_SIZE 4 /* Size of long instructions. */
868d8e32 1535
d868a170 1536/* Return the bytes needed to compute the frame pointer from the current
1537 stack pointer.
1538
1539 SIZE is the size needed for local variables. */
1540
1541unsigned int
aea2fd96 1542m32r_compute_frame_size (int size) /* # of var. bytes allocated. */
d868a170 1543{
58f4ce52 1544 unsigned int regno;
d868a170 1545 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
72061572 1546 unsigned int reg_size;
d868a170 1547 unsigned int gmask;
1548 enum m32r_function_type fn_type;
1549 int interrupt_p;
18d50ae6 1550 int pic_reg_used = flag_pic && (crtl->uses_pic_offset_table
1551 | crtl->profile);
d868a170 1552
1553 var_size = M32R_STACK_ALIGN (size);
abe32cce 1554 args_size = M32R_STACK_ALIGN (crtl->outgoing_args_size);
1555 pretend_size = crtl->args.pretend_args_size;
d868a170 1556 extra_size = FIRST_PARM_OFFSET (0);
1557 total_size = extra_size + pretend_size + args_size + var_size;
1558 reg_size = 0;
1559 gmask = 0;
1560
1561 /* See if this is an interrupt handler. Call used registers must be saved
1562 for them too. */
1563 fn_type = m32r_compute_function_type (current_function_decl);
1564 interrupt_p = M32R_INTERRUPT_P (fn_type);
1565
1566 /* Calculate space needed for registers. */
d868a170 1567 for (regno = 0; regno < M32R_MAX_INT_REGS; regno++)
1568 {
467dc9aa 1569 if (MUST_SAVE_REGISTER (regno, interrupt_p)
1570 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
d868a170 1571 {
1572 reg_size += UNITS_PER_WORD;
1573 gmask |= 1 << regno;
1574 }
1575 }
1576
1577 current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
467dc9aa 1578 current_frame_info.save_lr = MUST_SAVE_RETURN_ADDR || pic_reg_used;
d868a170 1579
1580 reg_size += ((current_frame_info.save_fp + current_frame_info.save_lr)
1581 * UNITS_PER_WORD);
1582 total_size += reg_size;
1583
b4d5d8b8 1584 /* ??? Not sure this is necessary, and I don't think the epilogue
d868a170 1585 handler will do the right thing if this changes total_size. */
1586 total_size = M32R_STACK_ALIGN (total_size);
1587
72061572 1588 /* frame_size = total_size - (pretend_size + reg_size); */
868d8e32 1589
d868a170 1590 /* Save computed information. */
1591 current_frame_info.total_size = total_size;
1592 current_frame_info.extra_size = extra_size;
1593 current_frame_info.pretend_size = pretend_size;
1594 current_frame_info.var_size = var_size;
1595 current_frame_info.args_size = args_size;
1596 current_frame_info.reg_size = reg_size;
1597 current_frame_info.gmask = gmask;
1598 current_frame_info.initialized = reload_completed;
1599
1600 /* Ok, we're done. */
1601 return total_size;
1602}
cd90919d 1603
1604/* Worker function for TARGET_CAN_ELIMINATE. */
1605
1606bool
1607m32r_can_eliminate (const int from, const int to)
1608{
1609 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
1610 ? ! frame_pointer_needed
1611 : true);
1612}
1613
d868a170 1614\f
467dc9aa 1615/* The table we use to reference PIC data. */
1616static rtx global_offset_table;
58f4ce52 1617
6440ef45 1618static void
1619m32r_reload_lr (rtx sp, int size)
1620{
1621 rtx lr = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
1622
1623 if (size == 0)
58f4ce52 1624 emit_insn (gen_movsi (lr, gen_frame_mem (Pmode, sp)));
84e0b98d 1625 else if (size < 32768)
58f4ce52 1626 emit_insn (gen_movsi (lr, gen_frame_mem (Pmode,
1627 gen_rtx_PLUS (Pmode, sp,
1628 GEN_INT (size)))));
6440ef45 1629 else
58f4ce52 1630 {
6440ef45 1631 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
1632
1633 emit_insn (gen_movsi (tmp, GEN_INT (size)));
1634 emit_insn (gen_addsi3 (tmp, tmp, sp));
58f4ce52 1635 emit_insn (gen_movsi (lr, gen_frame_mem (Pmode, tmp)));
6440ef45 1636 }
1637
18b42941 1638 emit_use (lr);
6440ef45 1639}
1640
467dc9aa 1641void
1642m32r_load_pic_register (void)
1643{
1644 global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1645 emit_insn (gen_get_pc (pic_offset_table_rtx, global_offset_table,
73a1a86f 1646 GEN_INT (TARGET_MODEL_SMALL)));
58f4ce52 1647
467dc9aa 1648 /* Need to emit this whether or not we obey regdecls,
1649 since setjmp/longjmp can cause life info to screw up. */
18b42941 1650 emit_use (pic_offset_table_rtx);
467dc9aa 1651}
1652
7dbe3569 1653/* Expand the m32r prologue as a series of insns. */
d868a170 1654
1655void
aea2fd96 1656m32r_expand_prologue (void)
d868a170 1657{
1658 int regno;
7dbe3569 1659 int frame_size;
947391dc 1660 unsigned int gmask;
18d50ae6 1661 int pic_reg_used = flag_pic && (crtl->uses_pic_offset_table
1662 | crtl->profile);
d868a170 1663
7dbe3569 1664 if (! current_frame_info.initialized)
1665 m32r_compute_frame_size (get_frame_size ());
868d8e32 1666
7dbe3569 1667 gmask = current_frame_info.gmask;
d868a170 1668
1669 /* These cases shouldn't happen. Catch them now. */
7afac3c3 1670 gcc_assert (current_frame_info.total_size || !gmask);
d868a170 1671
d868a170 1672 /* Allocate space for register arguments if this is a variadic function. */
1673 if (current_frame_info.pretend_size != 0)
31a162bd 1674 {
1675 /* Use a HOST_WIDE_INT temporary, since negating an unsigned int gives
1676 the wrong result on a 64-bit host. */
1677 HOST_WIDE_INT pretend_size = current_frame_info.pretend_size;
1678 emit_insn (gen_addsi3 (stack_pointer_rtx,
1679 stack_pointer_rtx,
1680 GEN_INT (-pretend_size)));
1681 }
d868a170 1682
1683 /* Save any registers we need to and set up fp. */
d868a170 1684 if (current_frame_info.save_fp)
7dbe3569 1685 emit_insn (gen_movsi_push (stack_pointer_rtx, frame_pointer_rtx));
d868a170 1686
1687 gmask &= ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK);
1688
1689 /* Save any needed call-saved regs (and call-used if this is an
1690 interrupt handler). */
1691 for (regno = 0; regno <= M32R_MAX_INT_REGS; ++regno)
1692 {
1693 if ((gmask & (1 << regno)) != 0)
7dbe3569 1694 emit_insn (gen_movsi_push (stack_pointer_rtx,
1695 gen_rtx_REG (Pmode, regno)));
d868a170 1696 }
1697
1698 if (current_frame_info.save_lr)
7dbe3569 1699 emit_insn (gen_movsi_push (stack_pointer_rtx,
1700 gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)));
d868a170 1701
1702 /* Allocate the stack frame. */
7dbe3569 1703 frame_size = (current_frame_info.total_size
1704 - (current_frame_info.pretend_size
1705 + current_frame_info.reg_size));
1706
d868a170 1707 if (frame_size == 0)
aea2fd96 1708 ; /* Nothing to do. */
d868a170 1709 else if (frame_size <= 32768)
7dbe3569 1710 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1711 GEN_INT (-frame_size)));
d868a170 1712 else
7dbe3569 1713 {
1714 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
aea2fd96 1715
7dbe3569 1716 emit_insn (gen_movsi (tmp, GEN_INT (frame_size)));
1717 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
1718 }
d868a170 1719
1720 if (frame_pointer_needed)
7dbe3569 1721 emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
1722
18d50ae6 1723 if (crtl->profile)
467dc9aa 1724 /* Push lr for mcount (form_pc, x). */
1725 emit_insn (gen_movsi_push (stack_pointer_rtx,
1726 gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)));
58f4ce52 1727
467dc9aa 1728 if (pic_reg_used)
6440ef45 1729 {
1730 m32r_load_pic_register ();
1731 m32r_reload_lr (stack_pointer_rtx,
18d50ae6 1732 (crtl->profile ? 0 : frame_size));
6440ef45 1733 }
467dc9aa 1734
18d50ae6 1735 if (crtl->profile && !pic_reg_used)
7dbe3569 1736 emit_insn (gen_blockage ());
1737}
1738
1739\f
1740/* Set up the stack and frame pointer (if desired) for the function.
1741 Note, if this is changed, you need to mirror the changes in
1742 m32r_compute_frame_size which calculates the prolog size. */
1743
17d9b0c3 1744static void
aea2fd96 1745m32r_output_function_prologue (FILE * file, HOST_WIDE_INT size)
7dbe3569 1746{
1747 enum m32r_function_type fn_type = m32r_compute_function_type (current_function_decl);
1748
1749 /* If this is an interrupt handler, mark it as such. */
1750 if (M32R_INTERRUPT_P (fn_type))
aea2fd96 1751 fprintf (file, "\t%s interrupt handler\n", ASM_COMMENT_START);
7dbe3569 1752
1753 if (! current_frame_info.initialized)
1754 m32r_compute_frame_size (size);
d868a170 1755
7dbe3569 1756 /* This is only for the human reader. */
1757 fprintf (file,
1758 "\t%s PROLOGUE, vars= %d, regs= %d, args= %d, extra= %d\n",
1759 ASM_COMMENT_START,
1760 current_frame_info.var_size,
1761 current_frame_info.reg_size / 4,
1762 current_frame_info.args_size,
1763 current_frame_info.extra_size);
d868a170 1764}
1765\f
58f4ce52 1766/* Output RTL to pop register REGNO from the stack. */
d868a170 1767
17d9b0c3 1768static void
58f4ce52 1769pop (int regno)
1770{
1771 rtx x;
1772
1773 x = emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno),
1774 stack_pointer_rtx));
ef51d1e3 1775 add_reg_note (x, REG_INC, stack_pointer_rtx);
58f4ce52 1776}
1777
1778/* Expand the m32r epilogue as a series of insns. */
1779
1780void
1781m32r_expand_epilogue (void)
d868a170 1782{
1783 int regno;
1784 int noepilogue = FALSE;
1785 int total_size;
d868a170 1786
7afac3c3 1787 gcc_assert (current_frame_info.initialized);
d868a170 1788 total_size = current_frame_info.total_size;
1789
1790 if (total_size == 0)
1791 {
1792 rtx insn = get_last_insn ();
1793
1794 /* If the last insn was a BARRIER, we don't have to write any code
1795 because a jump (aka return) was put there. */
452bfb8b 1796 if (insn && NOTE_P (insn))
d868a170 1797 insn = prev_nonnote_insn (insn);
452bfb8b 1798 if (insn && BARRIER_P (insn))
d868a170 1799 noepilogue = TRUE;
1800 }
1801
1802 if (!noepilogue)
1803 {
d868a170 1804 unsigned int var_size = current_frame_info.var_size;
1805 unsigned int args_size = current_frame_info.args_size;
1806 unsigned int gmask = current_frame_info.gmask;
18d50ae6 1807 int can_trust_sp_p = !cfun->calls_alloca;
58f4ce52 1808
1809 if (flag_exceptions)
1810 emit_insn (gen_blockage ());
d868a170 1811
1812 /* The first thing to do is point the sp at the bottom of the register
1813 save area. */
1814 if (can_trust_sp_p)
1815 {
1816 unsigned int reg_offset = var_size + args_size;
58f4ce52 1817
d868a170 1818 if (reg_offset == 0)
aea2fd96 1819 ; /* Nothing to do. */
d868a170 1820 else if (reg_offset < 32768)
58f4ce52 1821 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1822 GEN_INT (reg_offset)));
69e870b0 1823 else
58f4ce52 1824 {
1825 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
1826
1827 emit_insn (gen_movsi (tmp, GEN_INT (reg_offset)));
1828 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1829 tmp));
1830 }
d868a170 1831 }
1832 else if (frame_pointer_needed)
1833 {
1834 unsigned int reg_offset = var_size + args_size;
aea2fd96 1835
d868a170 1836 if (reg_offset == 0)
58f4ce52 1837 emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
d868a170 1838 else if (reg_offset < 32768)
58f4ce52 1839 emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
1840 GEN_INT (reg_offset)));
69e870b0 1841 else
58f4ce52 1842 {
1843 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
1844
1845 emit_insn (gen_movsi (tmp, GEN_INT (reg_offset)));
1846 emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
1847 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1848 tmp));
1849 }
d868a170 1850 }
1851 else
7afac3c3 1852 gcc_unreachable ();
d868a170 1853
1854 if (current_frame_info.save_lr)
58f4ce52 1855 pop (RETURN_ADDR_REGNUM);
d868a170 1856
1857 /* Restore any saved registers, in reverse order of course. */
1858 gmask &= ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK);
1859 for (regno = M32R_MAX_INT_REGS - 1; regno >= 0; --regno)
1860 {
1861 if ((gmask & (1L << regno)) != 0)
58f4ce52 1862 pop (regno);
d868a170 1863 }
1864
1865 if (current_frame_info.save_fp)
58f4ce52 1866 pop (FRAME_POINTER_REGNUM);
d868a170 1867
1868 /* Remove varargs area if present. */
d868a170 1869 if (current_frame_info.pretend_size != 0)
58f4ce52 1870 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1871 GEN_INT (current_frame_info.pretend_size)));
1872
1873 emit_insn (gen_blockage ());
d868a170 1874 }
58f4ce52 1875}
1876
1877/* Do any necessary cleanup after a function to restore stack, frame,
1878 and regs. */
d868a170 1879
58f4ce52 1880static void
1881m32r_output_function_epilogue (FILE * file ATTRIBUTE_UNUSED,
1882 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1883{
d868a170 1884 /* Reset state info for each function. */
1885 current_frame_info = zero_frame_info;
1886 m32r_compute_function_type (NULL_TREE);
1887}
947391dc 1888\f
e911aedf 1889/* Return nonzero if this function is known to have a null or 1 instruction
947391dc 1890 epilogue. */
1891
1892int
aea2fd96 1893direct_return (void)
947391dc 1894{
1895 if (!reload_completed)
1896 return FALSE;
1897
58f4ce52 1898 if (M32R_INTERRUPT_P (m32r_compute_function_type (current_function_decl)))
1899 return FALSE;
1900
947391dc 1901 if (! current_frame_info.initialized)
1902 m32r_compute_frame_size (get_frame_size ());
1903
58f4ce52 1904 return current_frame_info.total_size == 0;
947391dc 1905}
1906
d868a170 1907\f
aea2fd96 1908/* PIC. */
d868a170 1909
467dc9aa 1910int
1911m32r_legitimate_pic_operand_p (rtx x)
1912{
1913 if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
1914 return 0;
58f4ce52 1915
467dc9aa 1916 if (GET_CODE (x) == CONST
1917 && GET_CODE (XEXP (x, 0)) == PLUS
1918 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1919 || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
452bfb8b 1920 && (CONST_INT_P (XEXP (XEXP (x, 0), 1))))
467dc9aa 1921 return 0;
58f4ce52 1922
467dc9aa 1923 return 1;
1924}
1925
1926rtx
1927m32r_legitimize_pic_address (rtx orig, rtx reg)
1928{
1929#ifdef DEBUG_PIC
1930 printf("m32r_legitimize_pic_address()\n");
1931#endif
1932
1933 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1934 {
1935 rtx pic_ref, address;
467dc9aa 1936 int subregs = 0;
1937
1938 if (reg == 0)
1939 {
7afac3c3 1940 gcc_assert (!reload_in_progress && !reload_completed);
1941 reg = gen_reg_rtx (Pmode);
467dc9aa 1942
1943 subregs = 1;
1944 }
1945
1946 if (subregs)
1947 address = gen_reg_rtx (Pmode);
1948 else
1949 address = reg;
1950
18d50ae6 1951 crtl->uses_pic_offset_table = 1;
72afe58b 1952
1953 if (GET_CODE (orig) == LABEL_REF
1954 || (GET_CODE (orig) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (orig)))
1955 {
1956 emit_insn (gen_gotoff_load_addr (reg, orig));
1957 emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
1958 return reg;
1959 }
1960
467dc9aa 1961 emit_insn (gen_pic_load_addr (address, orig));
1962
1963 emit_insn (gen_addsi3 (address, address, pic_offset_table_rtx));
e265a6da 1964 pic_ref = gen_const_mem (Pmode, address);
72061572 1965 emit_move_insn (reg, pic_ref);
467dc9aa 1966 return reg;
1967 }
1968 else if (GET_CODE (orig) == CONST)
1969 {
1970 rtx base, offset;
1971
1972 if (GET_CODE (XEXP (orig, 0)) == PLUS
1973 && XEXP (XEXP (orig, 0), 1) == pic_offset_table_rtx)
1974 return orig;
1975
1976 if (reg == 0)
1977 {
7afac3c3 1978 gcc_assert (!reload_in_progress && !reload_completed);
1979 reg = gen_reg_rtx (Pmode);
467dc9aa 1980 }
1981
1982 if (GET_CODE (XEXP (orig, 0)) == PLUS)
1983 {
1984 base = m32r_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
1985 if (base == reg)
1986 offset = m32r_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), NULL_RTX);
1987 else
1988 offset = m32r_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), reg);
1989 }
1990 else
1991 return orig;
1992
452bfb8b 1993 if (CONST_INT_P (offset))
467dc9aa 1994 {
1995 if (INT16_P (INTVAL (offset)))
29c05e22 1996 return plus_constant (Pmode, base, INTVAL (offset));
467dc9aa 1997 else
7afac3c3 1998 {
1999 gcc_assert (! reload_in_progress && ! reload_completed);
2000 offset = force_reg (Pmode, offset);
2001 }
467dc9aa 2002 }
2003
1a83b3ff 2004 return gen_rtx_PLUS (Pmode, base, offset);
467dc9aa 2005 }
2006
2007 return orig;
2008}
41e3a0c7 2009
2010static rtx
2011m32r_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2012 enum machine_mode mode ATTRIBUTE_UNUSED)
2013{
2014 if (flag_pic)
2015 return m32r_legitimize_pic_address (x, NULL_RTX);
2016 else
2017 return x;
2018}
8c9a773b 2019
2020/* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P. */
2021
2022static bool
4e27ffd0 2023m32r_mode_dependent_address_p (const_rtx addr, addr_space_t as ATTRIBUTE_UNUSED)
8c9a773b 2024{
2025 if (GET_CODE (addr) == LO_SUM)
2026 return true;
2027
2028 return false;
2029}
d868a170 2030\f
2031/* Nested function support. */
2032
2033/* Emit RTL insns to initialize the variable parts of a trampoline.
2034 FNADDR is an RTX for the address of the function's pure code.
2035 CXT is an RTX for the static chain value for the function. */
2036
2037void
aea2fd96 2038m32r_initialize_trampoline (rtx tramp ATTRIBUTE_UNUSED,
2039 rtx fnaddr ATTRIBUTE_UNUSED,
2040 rtx cxt ATTRIBUTE_UNUSED)
d868a170 2041{
2042}
2043\f
92c473b8 2044static void
aea2fd96 2045m32r_file_start (void)
d868a170 2046{
92c473b8 2047 default_file_start ();
2048
d868a170 2049 if (flag_verbose_asm)
92c473b8 2050 fprintf (asm_out_file,
13a54dd9 2051 "%s M32R/D special options: -G %d\n",
d868a170 2052 ASM_COMMENT_START, g_switch_value);
467dc9aa 2053
2054 if (TARGET_LITTLE_ENDIAN)
2055 fprintf (asm_out_file, "\t.little\n");
d868a170 2056}
2057\f
2058/* Print operand X (an rtx) in assembler syntax to file FILE.
2059 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2060 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2061
8e8a63d1 2062static void
aea2fd96 2063m32r_print_operand (FILE * file, rtx x, int code)
d868a170 2064{
7dbe3569 2065 rtx addr;
2066
d868a170 2067 switch (code)
2068 {
173e37ab 2069 /* The 's' and 'p' codes are used by output_block_move() to
2070 indicate post-increment 's'tores and 'p're-increment loads. */
2071 case 's':
452bfb8b 2072 if (REG_P (x))
173e37ab 2073 fprintf (file, "@+%s", reg_names [REGNO (x)]);
2074 else
a1657b95 2075 output_operand_lossage ("invalid operand to %%s code");
173e37ab 2076 return;
58f4ce52 2077
173e37ab 2078 case 'p':
452bfb8b 2079 if (REG_P (x))
173e37ab 2080 fprintf (file, "@%s+", reg_names [REGNO (x)]);
2081 else
a1657b95 2082 output_operand_lossage ("invalid operand to %%p code");
173e37ab 2083 return;
2084
d868a170 2085 case 'R' :
2086 /* Write second word of DImode or DFmode reference,
2087 register or memory. */
452bfb8b 2088 if (REG_P (x))
d868a170 2089 fputs (reg_names[REGNO (x)+1], file);
452bfb8b 2090 else if (MEM_P (x))
d868a170 2091 {
2092 fprintf (file, "@(");
2093 /* Handle possible auto-increment. Since it is pre-increment and
2094 we have already done it, we can just use an offset of four. */
2095 /* ??? This is taken from rs6000.c I think. I don't think it is
2096 currently necessary, but keep it around. */
2097 if (GET_CODE (XEXP (x, 0)) == PRE_INC
2098 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
29c05e22 2099 output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
d868a170 2100 else
29c05e22 2101 output_address (plus_constant (Pmode, XEXP (x, 0), 4));
d868a170 2102 fputc (')', file);
2103 }
2104 else
a1657b95 2105 output_operand_lossage ("invalid operand to %%R code");
d868a170 2106 return;
2107
aea2fd96 2108 case 'H' : /* High word. */
2109 case 'L' : /* Low word. */
452bfb8b 2110 if (REG_P (x))
d868a170 2111 {
aea2fd96 2112 /* L = least significant word, H = most significant word. */
d868a170 2113 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
2114 fputs (reg_names[REGNO (x)], file);
2115 else
2116 fputs (reg_names[REGNO (x)+1], file);
2117 }
452bfb8b 2118 else if (CONST_INT_P (x)
d868a170 2119 || GET_CODE (x) == CONST_DOUBLE)
2120 {
2121 rtx first, second;
2122
2123 split_double (x, &first, &second);
6441a98f 2124 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
d868a170 2125 code == 'L' ? INTVAL (first) : INTVAL (second));
2126 }
2127 else
a1657b95 2128 output_operand_lossage ("invalid operand to %%H/%%L code");
d868a170 2129 return;
2130
2131 case 'A' :
2132 {
d868a170 2133 char str[30];
2134
2135 if (GET_CODE (x) != CONST_DOUBLE
2136 || GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT)
68435912 2137 fatal_insn ("bad insn for 'A'", x);
c7fbc741 2138
2139 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
d868a170 2140 fprintf (file, "%s", str);
2141 return;
2142 }
2143
aea2fd96 2144 case 'B' : /* Bottom half. */
2145 case 'T' : /* Top half. */
d868a170 2146 /* Output the argument to a `seth' insn (sets the Top half-word).
2147 For constants output arguments to a seth/or3 pair to set Top and
2148 Bottom halves. For symbols output arguments to a seth/add3 pair to
2149 set Top and Bottom halves. The difference exists because for
2150 constants seth/or3 is more readable but for symbols we need to use
c910419d 2151 the same scheme as `ld' and `st' insns (16-bit addend is signed). */
d868a170 2152 switch (GET_CODE (x))
2153 {
2154 case CONST_INT :
2155 case CONST_DOUBLE :
2156 {
2157 rtx first, second;
2158
2159 split_double (x, &first, &second);
2160 x = WORDS_BIG_ENDIAN ? second : first;
5c5d0ae9 2161 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
d868a170 2162 (code == 'B'
2163 ? INTVAL (x) & 0xffff
2164 : (INTVAL (x) >> 16) & 0xffff));
2165 }
2166 return;
2167 case CONST :
2168 case SYMBOL_REF :
2169 if (code == 'B'
2170 && small_data_operand (x, VOIDmode))
2171 {
2172 fputs ("sda(", file);
2173 output_addr_const (file, x);
2174 fputc (')', file);
2175 return;
2176 }
2177 /* fall through */
2178 case LABEL_REF :
2179 fputs (code == 'T' ? "shigh(" : "low(", file);
2180 output_addr_const (file, x);
2181 fputc (')', file);
2182 return;
2183 default :
a1657b95 2184 output_operand_lossage ("invalid operand to %%T/%%B code");
d868a170 2185 return;
2186 }
2187 break;
2188
2189 case 'U' :
8ec9afef 2190 /* ??? wip */
d868a170 2191 /* Output a load/store with update indicator if appropriate. */
452bfb8b 2192 if (MEM_P (x))
d868a170 2193 {
2194 if (GET_CODE (XEXP (x, 0)) == PRE_INC
2195 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
2196 fputs (".a", file);
2197 }
2198 else
a1657b95 2199 output_operand_lossage ("invalid operand to %%U code");
d868a170 2200 return;
2201
2202 case 'N' :
2203 /* Print a constant value negated. */
452bfb8b 2204 if (CONST_INT_P (x))
d868a170 2205 output_addr_const (file, GEN_INT (- INTVAL (x)));
2206 else
a1657b95 2207 output_operand_lossage ("invalid operand to %%N code");
d868a170 2208 return;
2209
205bb293 2210 case 'X' :
2211 /* Print a const_int in hex. Used in comments. */
452bfb8b 2212 if (CONST_INT_P (x))
5c5d0ae9 2213 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
205bb293 2214 return;
2215
d868a170 2216 case '#' :
2217 fputs (IMMEDIATE_PREFIX, file);
2218 return;
2219
d868a170 2220 case 0 :
2221 /* Do nothing special. */
2222 break;
2223
2224 default :
2225 /* Unknown flag. */
2226 output_operand_lossage ("invalid operand output code");
2227 }
2228
2229 switch (GET_CODE (x))
2230 {
2231 case REG :
2232 fputs (reg_names[REGNO (x)], file);
2233 break;
2234
2235 case MEM :
7dbe3569 2236 addr = XEXP (x, 0);
2237 if (GET_CODE (addr) == PRE_INC)
2238 {
452bfb8b 2239 if (!REG_P (XEXP (addr, 0)))
68435912 2240 fatal_insn ("pre-increment address is not a register", x);
7dbe3569 2241
2242 fprintf (file, "@+%s", reg_names[REGNO (XEXP (addr, 0))]);
2243 }
2244 else if (GET_CODE (addr) == PRE_DEC)
2245 {
452bfb8b 2246 if (!REG_P (XEXP (addr, 0)))
68435912 2247 fatal_insn ("pre-decrement address is not a register", x);
7dbe3569 2248
2249 fprintf (file, "@-%s", reg_names[REGNO (XEXP (addr, 0))]);
2250 }
2251 else if (GET_CODE (addr) == POST_INC)
2252 {
452bfb8b 2253 if (!REG_P (XEXP (addr, 0)))
68435912 2254 fatal_insn ("post-increment address is not a register", x);
7dbe3569 2255
2256 fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
2257 }
d868a170 2258 else
7dbe3569 2259 {
2260 fputs ("@(", file);
2261 output_address (XEXP (x, 0));
2262 fputc (')', file);
2263 }
d868a170 2264 break;
2265
2266 case CONST_DOUBLE :
2267 /* We handle SFmode constants here as output_addr_const doesn't. */
2268 if (GET_MODE (x) == SFmode)
2269 {
2270 REAL_VALUE_TYPE d;
2271 long l;
2272
2273 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
2274 REAL_VALUE_TO_TARGET_SINGLE (d, l);
2275 fprintf (file, "0x%08lx", l);
2276 break;
2277 }
2278
2279 /* Fall through. Let output_addr_const deal with it. */
2280
2281 default :
2282 output_addr_const (file, x);
2283 break;
2284 }
2285}
2286
2287/* Print a memory address as an operand to reference that memory location. */
2288
8e8a63d1 2289static void
aea2fd96 2290m32r_print_operand_address (FILE * file, rtx addr)
d868a170 2291{
aea2fd96 2292 rtx base;
2293 rtx index = 0;
2294 int offset = 0;
d868a170 2295
2296 switch (GET_CODE (addr))
2297 {
2298 case REG :
2299 fputs (reg_names[REGNO (addr)], file);
2300 break;
2301
2302 case PLUS :
452bfb8b 2303 if (CONST_INT_P (XEXP (addr, 0)))
d868a170 2304 offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
452bfb8b 2305 else if (CONST_INT_P (XEXP (addr, 1)))
d868a170 2306 offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
2307 else
2308 base = XEXP (addr, 0), index = XEXP (addr, 1);
452bfb8b 2309 if (REG_P (base))
d868a170 2310 {
2311 /* Print the offset first (if present) to conform to the manual. */
2312 if (index == 0)
2313 {
2314 if (offset != 0)
2315 fprintf (file, "%d,", offset);
2316 fputs (reg_names[REGNO (base)], file);
2317 }
2318 /* The chip doesn't support this, but left in for generality. */
452bfb8b 2319 else if (REG_P (index))
d868a170 2320 fprintf (file, "%s,%s",
2321 reg_names[REGNO (base)], reg_names[REGNO (index)]);
2322 /* Not sure this can happen, but leave in for now. */
2323 else if (GET_CODE (index) == SYMBOL_REF)
2324 {
2325 output_addr_const (file, index);
2326 fputc (',', file);
2327 fputs (reg_names[REGNO (base)], file);
2328 }
2329 else
68435912 2330 fatal_insn ("bad address", addr);
d868a170 2331 }
2332 else if (GET_CODE (base) == LO_SUM)
2333 {
452bfb8b 2334 gcc_assert (!index && REG_P (XEXP (base, 0)));
d868a170 2335 if (small_data_operand (XEXP (base, 1), VOIDmode))
2336 fputs ("sda(", file);
2337 else
2338 fputs ("low(", file);
29c05e22 2339 output_addr_const (file, plus_constant (Pmode, XEXP (base, 1),
2340 offset));
d868a170 2341 fputs ("),", file);
2342 fputs (reg_names[REGNO (XEXP (base, 0))], file);
2343 }
2344 else
68435912 2345 fatal_insn ("bad address", addr);
d868a170 2346 break;
2347
2348 case LO_SUM :
452bfb8b 2349 if (!REG_P (XEXP (addr, 0)))
68435912 2350 fatal_insn ("lo_sum not of register", addr);
d868a170 2351 if (small_data_operand (XEXP (addr, 1), VOIDmode))
2352 fputs ("sda(", file);
2353 else
2354 fputs ("low(", file);
2355 output_addr_const (file, XEXP (addr, 1));
2356 fputs ("),", file);
2357 fputs (reg_names[REGNO (XEXP (addr, 0))], file);
2358 break;
2359
aea2fd96 2360 case PRE_INC : /* Assume SImode. */
7dbe3569 2361 fprintf (file, "+%s", reg_names[REGNO (XEXP (addr, 0))]);
2362 break;
2363
aea2fd96 2364 case PRE_DEC : /* Assume SImode. */
7dbe3569 2365 fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]);
2366 break;
2367
aea2fd96 2368 case POST_INC : /* Assume SImode. */
7dbe3569 2369 fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]);
d868a170 2370 break;
2371
2372 default :
2373 output_addr_const (file, addr);
2374 break;
2375 }
2376}
868d8e32 2377
8e8a63d1 2378static bool
2379m32r_print_operand_punct_valid_p (unsigned char code)
2380{
2381 return m32r_punct_chars[code];
2382}
2383
868d8e32 2384/* Return true if the operands are the constants 0 and 1. */
aea2fd96 2385
868d8e32 2386int
aea2fd96 2387zero_and_one (rtx operand1, rtx operand2)
868d8e32 2388{
2389 return
452bfb8b 2390 CONST_INT_P (operand1)
2391 && CONST_INT_P (operand2)
868d8e32 2392 && ( ((INTVAL (operand1) == 0) && (INTVAL (operand2) == 1))
2393 ||((INTVAL (operand1) == 1) && (INTVAL (operand2) == 0)));
2394}
2395
868d8e32 2396/* Generate the correct assembler code to handle the conditional loading of a
2397 value into a register. It is known that the operands satisfy the
2398 conditional_move_operand() function above. The destination is operand[0].
2399 The condition is operand [1]. The 'true' value is operand [2] and the
2400 'false' value is operand [3]. */
aea2fd96 2401
868d8e32 2402char *
aea2fd96 2403emit_cond_move (rtx * operands, rtx insn ATTRIBUTE_UNUSED)
868d8e32 2404{
2405 static char buffer [100];
08c762a3 2406 const char * dest = reg_names [REGNO (operands [0])];
58f4ce52 2407
868d8e32 2408 buffer [0] = 0;
58f4ce52 2409
868d8e32 2410 /* Destination must be a register. */
452bfb8b 2411 gcc_assert (REG_P (operands [0]));
7afac3c3 2412 gcc_assert (conditional_move_operand (operands [2], SImode));
2413 gcc_assert (conditional_move_operand (operands [3], SImode));
58f4ce52 2414
868d8e32 2415 /* Check to see if the test is reversed. */
2416 if (GET_CODE (operands [1]) == NE)
2417 {
2418 rtx tmp = operands [2];
2419 operands [2] = operands [3];
2420 operands [3] = tmp;
2421 }
2422
60bbc120 2423 sprintf (buffer, "mvfc %s, cbr", dest);
03033f8f 2424
60bbc120 2425 /* If the true value was '0' then we need to invert the results of the move. */
2426 if (INTVAL (operands [2]) == 0)
2427 sprintf (buffer + strlen (buffer), "\n\txor3 %s, %s, #1",
2428 dest, dest);
03033f8f 2429
868d8e32 2430 return buffer;
2431}
2432
947391dc 2433/* Returns true if the registers contained in the two
1d60d981 2434 rtl expressions are different. */
aea2fd96 2435
947391dc 2436int
aea2fd96 2437m32r_not_same_reg (rtx a, rtx b)
947391dc 2438{
2439 int reg_a = -1;
2440 int reg_b = -2;
58f4ce52 2441
947391dc 2442 while (GET_CODE (a) == SUBREG)
2443 a = SUBREG_REG (a);
58f4ce52 2444
452bfb8b 2445 if (REG_P (a))
947391dc 2446 reg_a = REGNO (a);
58f4ce52 2447
947391dc 2448 while (GET_CODE (b) == SUBREG)
2449 b = SUBREG_REG (b);
58f4ce52 2450
452bfb8b 2451 if (REG_P (b))
947391dc 2452 reg_b = REGNO (b);
58f4ce52 2453
947391dc 2454 return reg_a != reg_b;
2455}
173e37ab 2456
2457\f
fe34fa5a 2458rtx
2459m32r_function_symbol (const char *name)
2460{
2461 int extra_flags = 0;
2462 enum m32r_model model;
2463 rtx sym = gen_rtx_SYMBOL_REF (Pmode, name);
2464
2465 if (TARGET_MODEL_SMALL)
2466 model = M32R_MODEL_SMALL;
2467 else if (TARGET_MODEL_MEDIUM)
2468 model = M32R_MODEL_MEDIUM;
2469 else if (TARGET_MODEL_LARGE)
2470 model = M32R_MODEL_LARGE;
2471 else
7afac3c3 2472 gcc_unreachable (); /* Shouldn't happen. */
fe34fa5a 2473 extra_flags |= model << SYMBOL_FLAG_MODEL_SHIFT;
58f4ce52 2474
fe34fa5a 2475 if (extra_flags)
2476 SYMBOL_REF_FLAGS (sym) |= extra_flags;
2477
2478 return sym;
2479}
2480
173e37ab 2481/* Use a library function to move some bytes. */
aea2fd96 2482
173e37ab 2483static void
a11b18dd 2484block_move_call (rtx dest_reg, rtx src_reg, rtx bytes_rtx)
173e37ab 2485{
2486 /* We want to pass the size as Pmode, which will normally be SImode
c910419d 2487 but will be DImode if we are using 64-bit longs and pointers. */
173e37ab 2488 if (GET_MODE (bytes_rtx) != VOIDmode
2489 && GET_MODE (bytes_rtx) != Pmode)
2490 bytes_rtx = convert_to_mode (Pmode, bytes_rtx, 1);
2491
ef51d1e3 2492 emit_library_call (m32r_function_symbol ("memcpy"), LCT_NORMAL,
173e37ab 2493 VOIDmode, 3, dest_reg, Pmode, src_reg, Pmode,
2494 convert_to_mode (TYPE_MODE (sizetype), bytes_rtx,
78a8ed03 2495 TYPE_UNSIGNED (sizetype)),
173e37ab 2496 TYPE_MODE (sizetype));
173e37ab 2497}
2498
173e37ab 2499/* Expand string/block move operations.
2500
2501 operands[0] is the pointer to the destination.
2502 operands[1] is the pointer to the source.
2503 operands[2] is the number of bytes to move.
9ca439fa 2504 operands[3] is the alignment.
173e37ab 2505
9ca439fa 2506 Returns 1 upon success, 0 otherwise. */
2507
2508int
aea2fd96 2509m32r_expand_block_move (rtx operands[])
173e37ab 2510{
2511 rtx orig_dst = operands[0];
2512 rtx orig_src = operands[1];
2513 rtx bytes_rtx = operands[2];
2514 rtx align_rtx = operands[3];
452bfb8b 2515 int constp = CONST_INT_P (bytes_rtx);
173e37ab 2516 HOST_WIDE_INT bytes = constp ? INTVAL (bytes_rtx) : 0;
2517 int align = INTVAL (align_rtx);
2518 int leftover;
2519 rtx src_reg;
2520 rtx dst_reg;
2521
2522 if (constp && bytes <= 0)
9ca439fa 2523 return 1;
173e37ab 2524
2525 /* Move the address into scratch registers. */
2526 dst_reg = copy_addr_to_reg (XEXP (orig_dst, 0));
2527 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
2528
2529 if (align > UNITS_PER_WORD)
2530 align = UNITS_PER_WORD;
2531
2532 /* If we prefer size over speed, always use a function call.
2533 If we do not know the size, use a function call.
2534 If the blocks are not word aligned, use a function call. */
2535 if (optimize_size || ! constp || align != UNITS_PER_WORD)
2536 {
2537 block_move_call (dst_reg, src_reg, bytes_rtx);
9ca439fa 2538 return 0;
173e37ab 2539 }
2540
2541 leftover = bytes % MAX_MOVE_BYTES;
2542 bytes -= leftover;
58f4ce52 2543
173e37ab 2544 /* If necessary, generate a loop to handle the bulk of the copy. */
2545 if (bytes)
2546 {
79f6a8ed 2547 rtx_code_label *label = NULL;
e51fa923 2548 rtx final_src = NULL_RTX;
f4a9eadc 2549 rtx at_a_time = GEN_INT (MAX_MOVE_BYTES);
2550 rtx rounded_total = GEN_INT (bytes);
76dad66d 2551 rtx new_dst_reg = gen_reg_rtx (SImode);
2552 rtx new_src_reg = gen_reg_rtx (SImode);
173e37ab 2553
2554 /* If we are going to have to perform this loop more than
2555 once, then generate a label and compute the address the
2556 source register will contain upon completion of the final
dfd1079d 2557 iteration. */
173e37ab 2558 if (bytes > MAX_MOVE_BYTES)
2559 {
2560 final_src = gen_reg_rtx (Pmode);
2561
2562 if (INT16_P(bytes))
f4a9eadc 2563 emit_insn (gen_addsi3 (final_src, src_reg, rounded_total));
173e37ab 2564 else
2565 {
f4a9eadc 2566 emit_insn (gen_movsi (final_src, rounded_total));
173e37ab 2567 emit_insn (gen_addsi3 (final_src, final_src, src_reg));
2568 }
2569
2570 label = gen_label_rtx ();
2571 emit_label (label);
2572 }
2573
2574 /* It is known that output_block_move() will update src_reg to point
2575 to the word after the end of the source block, and dst_reg to point
2576 to the last word of the destination block, provided that the block
2577 is MAX_MOVE_BYTES long. */
008c057d 2578 emit_insn (gen_movmemsi_internal (dst_reg, src_reg, at_a_time,
76dad66d 2579 new_dst_reg, new_src_reg));
2580 emit_move_insn (dst_reg, new_dst_reg);
2581 emit_move_insn (src_reg, new_src_reg);
173e37ab 2582 emit_insn (gen_addsi3 (dst_reg, dst_reg, GEN_INT (4)));
58f4ce52 2583
173e37ab 2584 if (bytes > MAX_MOVE_BYTES)
2585 {
74f4459c 2586 rtx test = gen_rtx_NE (VOIDmode, src_reg, final_src);
2587 emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
173e37ab 2588 }
2589 }
2590
2591 if (leftover)
008c057d 2592 emit_insn (gen_movmemsi_internal (dst_reg, src_reg, GEN_INT (leftover),
76dad66d 2593 gen_reg_rtx (SImode),
2594 gen_reg_rtx (SImode)));
9ca439fa 2595 return 1;
173e37ab 2596}
2597
2598\f
58f4ce52 2599/* Emit load/stores for a small constant word aligned block_move.
173e37ab 2600
2601 operands[0] is the memory address of the destination.
2602 operands[1] is the memory address of the source.
2603 operands[2] is the number of bytes to move.
2604 operands[3] is a temp register.
2605 operands[4] is a temp register. */
2606
03033f8f 2607void
aea2fd96 2608m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
173e37ab 2609{
2610 HOST_WIDE_INT bytes = INTVAL (operands[2]);
2611 int first_time;
2612 int got_extra = 0;
58f4ce52 2613
7afac3c3 2614 gcc_assert (bytes >= 1 && bytes <= MAX_MOVE_BYTES);
58f4ce52 2615
173e37ab 2616 /* We do not have a post-increment store available, so the first set of
2617 stores are done without any increment, then the remaining ones can use
2618 the pre-increment addressing mode.
58f4ce52 2619
e911aedf 2620 Note: expand_block_move() also relies upon this behavior when building
173e37ab 2621 loops to copy large blocks. */
2622 first_time = 1;
58f4ce52 2623
173e37ab 2624 while (bytes > 0)
2625 {
2626 if (bytes >= 8)
2627 {
2628 if (first_time)
2629 {
76dad66d 2630 output_asm_insn ("ld\t%5, %p1", operands);
2631 output_asm_insn ("ld\t%6, %p1", operands);
2632 output_asm_insn ("st\t%5, @%0", operands);
2633 output_asm_insn ("st\t%6, %s0", operands);
173e37ab 2634 }
2635 else
2636 {
76dad66d 2637 output_asm_insn ("ld\t%5, %p1", operands);
2638 output_asm_insn ("ld\t%6, %p1", operands);
2639 output_asm_insn ("st\t%5, %s0", operands);
2640 output_asm_insn ("st\t%6, %s0", operands);
173e37ab 2641 }
2642
2643 bytes -= 8;
2644 }
2645 else if (bytes >= 4)
2646 {
2647 if (bytes > 4)
2648 got_extra = 1;
58f4ce52 2649
76dad66d 2650 output_asm_insn ("ld\t%5, %p1", operands);
58f4ce52 2651
173e37ab 2652 if (got_extra)
76dad66d 2653 output_asm_insn ("ld\t%6, %p1", operands);
58f4ce52 2654
173e37ab 2655 if (first_time)
76dad66d 2656 output_asm_insn ("st\t%5, @%0", operands);
173e37ab 2657 else
76dad66d 2658 output_asm_insn ("st\t%5, %s0", operands);
173e37ab 2659
2660 bytes -= 4;
2661 }
58f4ce52 2662 else
173e37ab 2663 {
2664 /* Get the entire next word, even though we do not want all of it.
2665 The saves us from doing several smaller loads, and we assume that
2666 we cannot cause a page fault when at least part of the word is in
f4a9eadc 2667 valid memory [since we don't get called if things aren't properly
2668 aligned]. */
2669 int dst_offset = first_time ? 0 : 4;
76dad66d 2670 /* The amount of increment we have to make to the
2671 destination pointer. */
2672 int dst_inc_amount = dst_offset + bytes - 4;
2673 /* The same for the source pointer. */
2674 int src_inc_amount = bytes;
f4a9eadc 2675 int last_shift;
2676 rtx my_operands[3];
2677
2678 /* If got_extra is true then we have already loaded
173e37ab 2679 the next word as part of loading and storing the previous word. */
2680 if (! got_extra)
76dad66d 2681 output_asm_insn ("ld\t%6, @%1", operands);
173e37ab 2682
2683 if (bytes >= 2)
2684 {
2685 bytes -= 2;
2686
76dad66d 2687 output_asm_insn ("sra3\t%5, %6, #16", operands);
2688 my_operands[0] = operands[5];
f4a9eadc 2689 my_operands[1] = GEN_INT (dst_offset);
2690 my_operands[2] = operands[0];
2691 output_asm_insn ("sth\t%0, @(%1,%2)", my_operands);
58f4ce52 2692
173e37ab 2693 /* If there is a byte left to store then increment the
2694 destination address and shift the contents of the source
f4a9eadc 2695 register down by 8 bits. We could not do the address
173e37ab 2696 increment in the store half word instruction, because it does
2697 not have an auto increment mode. */
2698 if (bytes > 0) /* assert (bytes == 1) */
2699 {
f4a9eadc 2700 dst_offset += 2;
2701 last_shift = 8;
173e37ab 2702 }
2703 }
f4a9eadc 2704 else
2705 last_shift = 24;
2706
2707 if (bytes > 0)
2708 {
76dad66d 2709 my_operands[0] = operands[6];
f4a9eadc 2710 my_operands[1] = GEN_INT (last_shift);
2711 output_asm_insn ("srai\t%0, #%1", my_operands);
76dad66d 2712 my_operands[0] = operands[6];
f4a9eadc 2713 my_operands[1] = GEN_INT (dst_offset);
2714 my_operands[2] = operands[0];
2715 output_asm_insn ("stb\t%0, @(%1,%2)", my_operands);
2716 }
76dad66d 2717
2718 /* Update the destination pointer if needed. We have to do
2719 this so that the patterns matches what we output in this
2720 function. */
2721 if (dst_inc_amount
2722 && !find_reg_note (insn, REG_UNUSED, operands[0]))
2723 {
2724 my_operands[0] = operands[0];
2725 my_operands[1] = GEN_INT (dst_inc_amount);
2726 output_asm_insn ("addi\t%0, #%1", my_operands);
2727 }
58f4ce52 2728
76dad66d 2729 /* Update the source pointer if needed. We have to do this
2730 so that the patterns matches what we output in this
2731 function. */
2732 if (src_inc_amount
2733 && !find_reg_note (insn, REG_UNUSED, operands[1]))
2734 {
2735 my_operands[0] = operands[1];
2736 my_operands[1] = GEN_INT (src_inc_amount);
2737 output_asm_insn ("addi\t%0, #%1", my_operands);
2738 }
58f4ce52 2739
173e37ab 2740 bytes = 0;
2741 }
2742
2743 first_time = 0;
2744 }
173e37ab 2745}
2746
d741027b 2747/* Return true if using NEW_REG in place of OLD_REG is ok. */
2748
2749int
aea2fd96 2750m32r_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
2751 unsigned int new_reg)
d741027b 2752{
2753 /* Interrupt routines can't clobber any register that isn't already used. */
2754 if (lookup_attribute ("interrupt", DECL_ATTRIBUTES (current_function_decl))
3072d30e 2755 && !df_regs_ever_live_p (new_reg))
d741027b 2756 return 0;
2757
d741027b 2758 return 1;
2759}
6440ef45 2760
2761rtx
2762m32r_return_addr (int count)
2763{
2764 if (count != 0)
2765 return const0_rtx;
58f4ce52 2766
6440ef45 2767 return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
2768}
06b77609 2769
2770static void
2771m32r_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
2772{
2773 emit_move_insn (adjust_address (m_tramp, SImode, 0),
2774 gen_int_mode (TARGET_LITTLE_ENDIAN ?
2775 0x017e8e17 : 0x178e7e01, SImode));
2776 emit_move_insn (adjust_address (m_tramp, SImode, 4),
2777 gen_int_mode (TARGET_LITTLE_ENDIAN ?
2778 0x0c00ae86 : 0x86ae000c, SImode));
2779 emit_move_insn (adjust_address (m_tramp, SImode, 8),
2780 gen_int_mode (TARGET_LITTLE_ENDIAN ?
2781 0xe627871e : 0x1e8727e6, SImode));
2782 emit_move_insn (adjust_address (m_tramp, SImode, 12),
2783 gen_int_mode (TARGET_LITTLE_ENDIAN ?
2784 0xc616c626 : 0x26c61fc6, SImode));
2785 emit_move_insn (adjust_address (m_tramp, SImode, 16),
2786 chain_value);
2787 emit_move_insn (adjust_address (m_tramp, SImode, 20),
2788 XEXP (DECL_RTL (fndecl), 0));
2789
2790 if (m32r_cache_flush_trap >= 0)
2791 emit_insn (gen_flush_icache
2792 (validize_mem (adjust_address (m_tramp, SImode, 0)),
2793 gen_int_mode (m32r_cache_flush_trap, SImode)));
2794 else if (m32r_cache_flush_func && m32r_cache_flush_func[0])
2795 emit_library_call (m32r_function_symbol (m32r_cache_flush_func),
2796 LCT_NORMAL, VOIDmode, 3, XEXP (m_tramp, 0), Pmode,
2797 gen_int_mode (TRAMPOLINE_SIZE, SImode), SImode,
2798 GEN_INT (3), SImode);
2799}
b2d7ede1 2800
bb10104e 2801/* True if X is a reg that can be used as a base reg. */
2802
2803static bool
2804m32r_rtx_ok_for_base_p (const_rtx x, bool strict)
2805{
2806 if (! REG_P (x))
2807 return false;
2808
2809 if (strict)
2810 {
2811 if (GPR_P (REGNO (x)))
2812 return true;
2813 }
2814 else
2815 {
2816 if (GPR_P (REGNO (x))
2817 || REGNO (x) == ARG_POINTER_REGNUM
2818 || ! HARD_REGISTER_P (x))
2819 return true;
2820 }
2821
2822 return false;
2823}
2824
2825static inline bool
2826m32r_rtx_ok_for_offset_p (const_rtx x)
2827{
2828 return (CONST_INT_P (x) && INT16_P (INTVAL (x)));
2829}
2830
2831static inline bool
2832m32r_legitimate_offset_addres_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2833 const_rtx x, bool strict)
2834{
2835 if (GET_CODE (x) == PLUS
2836 && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict)
2837 && m32r_rtx_ok_for_offset_p (XEXP (x, 1)))
2838 return true;
2839
2840 return false;
2841}
2842
2843/* For LO_SUM addresses, do not allow them if the MODE is > 1 word,
2844 since more than one instruction will be required. */
2845
2846static inline bool
2847m32r_legitimate_lo_sum_addres_p (enum machine_mode mode, const_rtx x,
2848 bool strict)
2849{
2850 if (GET_CODE (x) == LO_SUM
2851 && (mode != BLKmode && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2852 && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict)
2853 && CONSTANT_P (XEXP (x, 1)))
2854 return true;
2855
2856 return false;
2857}
2858
2859/* Is this a load and increment operation. */
2860
2861static inline bool
2862m32r_load_postinc_p (enum machine_mode mode, const_rtx x, bool strict)
2863{
2864 if ((mode == SImode || mode == SFmode)
2865 && GET_CODE (x) == POST_INC
2866 && REG_P (XEXP (x, 0))
2867 && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict))
2868 return true;
2869
2870 return false;
2871}
2872
2873/* Is this an increment/decrement and store operation. */
2874
2875static inline bool
2876m32r_store_preinc_predec_p (enum machine_mode mode, const_rtx x, bool strict)
2877{
2878 if ((mode == SImode || mode == SFmode)
2879 && (GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
2880 && REG_P (XEXP (x, 0)) \
2881 && m32r_rtx_ok_for_base_p (XEXP (x, 0), strict))
2882 return true;
2883
2884 return false;
2885}
2886
2887/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
2888
2889static bool
2890m32r_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
2891{
2892 if (m32r_rtx_ok_for_base_p (x, strict)
2893 || m32r_legitimate_offset_addres_p (mode, x, strict)
2894 || m32r_legitimate_lo_sum_addres_p (mode, x, strict)
2895 || m32r_load_postinc_p (mode, x, strict)
2896 || m32r_store_preinc_predec_p (mode, x, strict))
2897 return true;
2898
2899 return false;
2900}
2901
b2d7ede1 2902static void
2903m32r_conditional_register_usage (void)
2904{
2905 if (flag_pic)
2906 {
2907 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
2908 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
2909 }
2910}
ca316360 2911
2912/* Implement TARGET_LEGITIMATE_CONSTANT_P
2913
2914 We don't allow (plus symbol large-constant) as the relocations can't
2915 describe it. INTVAL > 32767 handles both 16-bit and 24-bit relocations.
2916 We allow all CONST_DOUBLE's as the md file patterns will force the
2917 constant to memory if they can't handle them. */
2918
2919static bool
2920m32r_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2921{
2922 return !(GET_CODE (x) == CONST
2923 && GET_CODE (XEXP (x, 0)) == PLUS
2924 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
2925 || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
2926 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
2927 && UINTVAL (XEXP (XEXP (x, 0), 1)) > 32767);
2928}