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