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