]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/m32r/m32r.c
Merge in gcc2-ss-010999
[thirdparty/gcc.git] / gcc / config / m32r / m32r.c
CommitLineData
2e076ddf 1/* Subroutines used for code generation on the Mitsubishi M32R cpu.
c5c76735 2 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
8c5ca3b9
DE
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
8c5ca3b9 21#include "config.h"
5b8ae21f 22#include "system.h"
8c5ca3b9
DE
23#include "tree.h"
24#include "rtl.h"
25#include "regs.h"
26#include "hard-reg-set.h"
27#include "real.h"
28#include "insn-config.h"
29#include "conditions.h"
30#include "insn-flags.h"
31#include "output.h"
32#include "insn-attr.h"
33#include "flags.h"
34#include "expr.h"
bf6bb899 35#include "function.h"
8c5ca3b9
DE
36#include "recog.h"
37
38/* Save the operands last given to a compare for use when we
39 generate a scc or bcc insn. */
40rtx m32r_compare_op0, m32r_compare_op1;
41
42/* Array of valid operand punctuation characters. */
43char m32r_punct_chars[256];
44
8c5ca3b9
DE
45/* Selected code model. */
46char *m32r_model_string = M32R_MODEL_DEFAULT;
47enum m32r_model m32r_model;
48
49/* Selected SDA support. */
50char *m32r_sdata_string = M32R_SDATA_DEFAULT;
51enum m32r_sdata m32r_sdata;
52
2b7972b0
MM
53
54/* Forward declaration. */
55static void init_reg_tables PROTO((void));
56
8c5ca3b9
DE
57/* Called by OVERRIDE_OPTIONS to initialize various things. */
58
59void
60m32r_init ()
61{
62 init_reg_tables ();
63
64 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
65 memset (m32r_punct_chars, 0, sizeof (m32r_punct_chars));
66 m32r_punct_chars['#'] = 1;
67 m32r_punct_chars['@'] = 1; /* ??? no longer used */
68
69 /* Provide default value if not specified. */
70 if (!g_switch_set)
71 g_switch_value = SDATA_DEFAULT_SIZE;
72
73 if (strcmp (m32r_model_string, "small") == 0)
74 m32r_model = M32R_MODEL_SMALL;
75 else if (strcmp (m32r_model_string, "medium") == 0)
76 m32r_model = M32R_MODEL_MEDIUM;
77 else if (strcmp (m32r_model_string, "large") == 0)
78 m32r_model = M32R_MODEL_LARGE;
79 else
80 error ("bad value (%s) for -mmodel switch", m32r_model_string);
81
82 if (strcmp (m32r_sdata_string, "none") == 0)
83 m32r_sdata = M32R_SDATA_NONE;
84 else if (strcmp (m32r_sdata_string, "sdata") == 0)
85 m32r_sdata = M32R_SDATA_SDATA;
86 else if (strcmp (m32r_sdata_string, "use") == 0)
87 m32r_sdata = M32R_SDATA_USE;
88 else
89 error ("bad value (%s) for -msdata switch", m32r_sdata_string);
2b7972b0 90
8c5ca3b9
DE
91}
92
93/* Vectors to keep interesting information about registers where it can easily
94 be got. We use to use the actual mode value as the bit number, but there
95 is (or may be) more than 32 modes now. Instead we use two tables: one
96 indexed by hard register number, and one indexed by mode. */
97
98/* The purpose of m32r_mode_class is to shrink the range of modes so that
99 they all fit (as bit numbers) in a 32 bit word (again). Each real mode is
100 mapped into one m32r_mode_class mode. */
101
2b7972b0
MM
102enum m32r_mode_class
103{
8c5ca3b9
DE
104 C_MODE,
105 S_MODE, D_MODE, T_MODE, O_MODE,
106 SF_MODE, DF_MODE, TF_MODE, OF_MODE
107};
108
109/* Modes for condition codes. */
110#define C_MODES (1 << (int) C_MODE)
111
112/* Modes for single-word and smaller quantities. */
113#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
114
115/* Modes for double-word and smaller quantities. */
116#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
117
118/* Modes for quad-word and smaller quantities. */
119#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
120
2b7972b0 121
8c5ca3b9
DE
122/* Value is 1 if register/mode pair is acceptable on arc. */
123
2b7972b0
MM
124unsigned int m32r_hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] =
125{
8c5ca3b9
DE
126 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
127 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, S_MODES, S_MODES, S_MODES,
128 S_MODES, C_MODES
129};
130
131unsigned int m32r_mode_class [NUM_MACHINE_MODES];
132
133enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
134
135static void
136init_reg_tables ()
137{
138 int i;
139
140 for (i = 0; i < NUM_MACHINE_MODES; i++)
141 {
142 switch (GET_MODE_CLASS (i))
143 {
144 case MODE_INT:
145 case MODE_PARTIAL_INT:
146 case MODE_COMPLEX_INT:
147 if (GET_MODE_SIZE (i) <= 4)
148 m32r_mode_class[i] = 1 << (int) S_MODE;
149 else if (GET_MODE_SIZE (i) == 8)
150 m32r_mode_class[i] = 1 << (int) D_MODE;
151 else if (GET_MODE_SIZE (i) == 16)
152 m32r_mode_class[i] = 1 << (int) T_MODE;
153 else if (GET_MODE_SIZE (i) == 32)
154 m32r_mode_class[i] = 1 << (int) O_MODE;
155 else
156 m32r_mode_class[i] = 0;
157 break;
158 case MODE_FLOAT:
159 case MODE_COMPLEX_FLOAT:
160 if (GET_MODE_SIZE (i) <= 4)
161 m32r_mode_class[i] = 1 << (int) SF_MODE;
162 else if (GET_MODE_SIZE (i) == 8)
163 m32r_mode_class[i] = 1 << (int) DF_MODE;
164 else if (GET_MODE_SIZE (i) == 16)
165 m32r_mode_class[i] = 1 << (int) TF_MODE;
166 else if (GET_MODE_SIZE (i) == 32)
167 m32r_mode_class[i] = 1 << (int) OF_MODE;
168 else
169 m32r_mode_class[i] = 0;
170 break;
171 case MODE_CC:
172 default:
173 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
174 we must explicitly check for them here. */
175 if (i == (int) CCmode)
176 m32r_mode_class[i] = 1 << (int) C_MODE;
177 else
178 m32r_mode_class[i] = 0;
179 break;
180 }
181 }
182
183 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
184 {
185 if (GPR_P (i))
186 m32r_regno_reg_class[i] = GENERAL_REGS;
187 else if (i == ARG_POINTER_REGNUM)
188 m32r_regno_reg_class[i] = GENERAL_REGS;
189 else
190 m32r_regno_reg_class[i] = NO_REGS;
191 }
192}
193\f
194/* M32R specific attribute support.
195
196 interrupt - for interrupt functions
197
198 model - select code model used to access object
199
200 small: addresses use 24 bits, use bl to make calls
201 medium: addresses use 32 bits, use bl to make calls
202 large: addresses use 32 bits, use seth/add3/jl to make calls
203
204 Grep for MODEL in m32r.h for more info.
205*/
206
6aa489b4
NC
207static tree interrupt_ident1;
208static tree interrupt_ident2;
209static tree model_ident1;
210static tree model_ident2;
211static tree small_ident1;
212static tree small_ident2;
213static tree medium_ident1;
214static tree medium_ident2;
215static tree large_ident1;
216static tree large_ident2;
217
218static void
219init_idents PROTO ((void))
220{
221 if (interrupt_ident1 == 0)
222 {
223 interrupt_ident1 = get_identifier ("interrupt");
224 interrupt_ident2 = get_identifier ("__interrupt__");
225 model_ident1 = get_identifier ("model");
226 model_ident2 = get_identifier ("__model__");
227 small_ident1 = get_identifier ("small");
228 small_ident2 = get_identifier ("__small__");
229 medium_ident1 = get_identifier ("medium");
230 medium_ident2 = get_identifier ("__medium__");
231 large_ident1 = get_identifier ("large");
232 large_ident2 = get_identifier ("__large__");
233 }
234}
235
8c5ca3b9
DE
236/* Return nonzero if IDENTIFIER is a valid decl attribute. */
237
238int
239m32r_valid_machine_decl_attribute (type, attributes, identifier, args)
240 tree type;
241 tree attributes;
242 tree identifier;
243 tree args;
244{
dd535142 245 init_idents ();
8c5ca3b9 246
6aa489b4
NC
247 if ((identifier == interrupt_ident1
248 || identifier == interrupt_ident2)
8c5ca3b9
DE
249 && list_length (args) == 0)
250 return 1;
251
6aa489b4
NC
252 if ((identifier == model_ident1
253 || identifier == model_ident2)
8c5ca3b9 254 && list_length (args) == 1
6aa489b4
NC
255 && (TREE_VALUE (args) == small_ident1
256 || TREE_VALUE (args) == small_ident2
257 || TREE_VALUE (args) == medium_ident1
258 || TREE_VALUE (args) == medium_ident2
259 || TREE_VALUE (args) == large_ident1
260 || TREE_VALUE (args) == large_ident2))
8c5ca3b9
DE
261 return 1;
262
263 return 0;
264}
265
266/* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
267 and two if they are nearly compatible (which causes a warning to be
268 generated). */
269
270int
271m32r_comp_type_attributes (type1, type2)
272 tree type1, type2;
273{
274 return 1;
275}
276
277/* Set the default attributes for TYPE. */
278
279void
280m32r_set_default_type_attributes (type)
281 tree type;
282{
283}
284\f
285/* A C statement or statements to switch to the appropriate
286 section for output of DECL. DECL is either a `VAR_DECL' node
287 or a constant of some sort. RELOC indicates whether forming
288 the initial value of DECL requires link-time relocations. */
289
290void
291m32r_select_section (decl, reloc)
292 tree decl;
293 int reloc;
294{
295 if (TREE_CODE (decl) == STRING_CST)
296 {
297 if (! flag_writable_strings)
298 const_section ();
299 else
300 data_section ();
301 }
302 else if (TREE_CODE (decl) == VAR_DECL)
303 {
304 if (SDATA_NAME_P (XSTR (XEXP (DECL_RTL (decl), 0), 0)))
305 sdata_section ();
306 else if ((flag_pic && reloc)
307 || !TREE_READONLY (decl)
308 || TREE_SIDE_EFFECTS (decl)
309 || !DECL_INITIAL (decl)
310 || (DECL_INITIAL (decl) != error_mark_node
311 && !TREE_CONSTANT (DECL_INITIAL (decl))))
312 data_section ();
313 else
314 const_section ();
315 }
316 else
317 const_section ();
318}
319
320/* Encode section information of DECL, which is either a VAR_DECL,
321 FUNCTION_DECL, STRING_CST, CONSTRUCTOR, or ???.
322
323 For the M32R we want to record:
324
325 - whether the object lives in .sdata/.sbss.
326 objects living in .sdata/.sbss are prefixed with SDATA_FLAG_CHAR
327
328 - what code model should be used to access the object
329 small: recorded with no flag - for space efficiency since they'll
330 be the most common
331 medium: prefixed with MEDIUM_FLAG_CHAR
332 large: prefixed with LARGE_FLAG_CHAR
333*/
334
335void
336m32r_encode_section_info (decl)
337 tree decl;
338{
339 char prefix = 0;
340 tree model = 0;
341
342 switch (TREE_CODE (decl))
343 {
344 case VAR_DECL :
345 case FUNCTION_DECL :
346 model = lookup_attribute ("model", DECL_MACHINE_ATTRIBUTES (decl));
347 break;
348 case STRING_CST :
349 case CONSTRUCTOR :
350 /* ??? document all others that can appear here */
351 default :
352 return;
353 }
354
355 /* Only mark the object as being small data area addressable if
356 it hasn't been explicitly marked with a code model.
357
358 The user can explicitly put an object in the small data area with the
359 section attribute. If the object is in sdata/sbss and marked with a
360 code model do both [put the object in .sdata and mark it as being
361 addressed with a specific code model - don't mark it as being addressed
362 with an SDA reloc though]. This is ok and might be useful at times. If
363 the object doesn't fit the linker will give an error. */
364
365 if (! model)
366 {
367 if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
368 && DECL_SECTION_NAME (decl) != NULL_TREE)
369 {
370 char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
371 if (! strcmp (name, ".sdata") || ! strcmp (name, ".sbss"))
372 {
373#if 0 /* ??? There's no reason to disallow this, is there? */
374 if (TREE_READONLY (decl))
375 error_with_decl (decl, "const objects cannot go in .sdata/.sbss");
376#endif
377 prefix = SDATA_FLAG_CHAR;
378 }
379 }
380 else
381 {
382 if (TREE_CODE (decl) == VAR_DECL
383 && ! TREE_READONLY (decl)
384 && ! TARGET_SDATA_NONE)
385 {
386 int size = int_size_in_bytes (TREE_TYPE (decl));
387
388 if (size > 0 && size <= g_switch_value)
389 prefix = SDATA_FLAG_CHAR;
390 }
391 }
392 }
393
394 /* If data area not decided yet, check for a code model. */
395 if (prefix == 0)
396 {
397 if (model)
398 {
6aa489b4 399 tree id;
dd535142 400
6aa489b4
NC
401 init_idents ();
402
403 id = TREE_VALUE (TREE_VALUE (model));
404
405 if (id == small_ident1 || id == small_ident2)
8c5ca3b9 406 ; /* don't mark the symbol specially */
6aa489b4 407 else if (id == medium_ident1 || id == medium_ident2)
8c5ca3b9 408 prefix = MEDIUM_FLAG_CHAR;
6aa489b4 409 else if (id == large_ident1 || id == large_ident2)
8c5ca3b9
DE
410 prefix = LARGE_FLAG_CHAR;
411 else
412 abort (); /* shouldn't happen */
413 }
414 else
415 {
416 if (TARGET_MODEL_SMALL)
417 ; /* don't mark the symbol specially */
418 else if (TARGET_MODEL_MEDIUM)
419 prefix = MEDIUM_FLAG_CHAR;
420 else if (TARGET_MODEL_LARGE)
421 prefix = LARGE_FLAG_CHAR;
422 else
423 abort (); /* shouldn't happen */
424 }
425 }
426
427 if (prefix != 0)
428 {
429 rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
430 ? TREE_CST_RTL (decl) : DECL_RTL (decl));
431 char *str = XSTR (XEXP (rtl, 0), 0);
432 int len = strlen (str);
433 char *newstr = savealloc (len + 2);
434 strcpy (newstr + 1, str);
435 *newstr = prefix;
436 XSTR (XEXP (rtl, 0), 0) = newstr;
437 }
438}
439
440/* Do anything needed before RTL is emitted for each function. */
441
442void
443m32r_init_expanders ()
444{
445 /* ??? At one point there was code here. The function is left in
446 to make it easy to experiment. */
447}
448\f
449/* Acceptable arguments to the call insn. */
450
451int
2b7972b0 452call_address_operand (op, int_mode)
8c5ca3b9 453 rtx op;
2b7972b0 454 int int_mode;
8c5ca3b9 455{
2b7972b0 456 return symbolic_operand (op, int_mode);
2e076ddf 457
2b7972b0
MM
458/* Constants and values in registers are not OK, because
459 the m32r BL instruction can only support PC relative branching. */
8c5ca3b9
DE
460}
461
462int
2b7972b0 463call_operand (op, int_mode)
8c5ca3b9 464 rtx op;
2b7972b0 465 int int_mode;
8c5ca3b9 466{
2b7972b0
MM
467 enum machine_mode mode = (enum machine_mode)int_mode;
468
8c5ca3b9
DE
469 if (GET_CODE (op) != MEM)
470 return 0;
471 op = XEXP (op, 0);
472 return call_address_operand (op, mode);
473}
474
475/* Returns 1 if OP is a symbol reference. */
476
477int
2b7972b0 478symbolic_operand (op, int_mode)
8c5ca3b9 479 rtx op;
2b7972b0 480 int int_mode;
8c5ca3b9
DE
481{
482 switch (GET_CODE (op))
483 {
484 case SYMBOL_REF:
485 case LABEL_REF:
486 case CONST :
487 return 1;
2b7972b0 488
8c5ca3b9
DE
489 default:
490 return 0;
491 }
492}
493
8c5ca3b9
DE
494/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
495
496int
2b7972b0 497small_data_operand (op, int_mode)
8c5ca3b9 498 rtx op;
2b7972b0 499 int int_mode;
8c5ca3b9
DE
500{
501 if (! TARGET_SDATA_USE)
502 return 0;
503
504 if (GET_CODE (op) == SYMBOL_REF)
505 return SDATA_NAME_P (XSTR (op, 0));
506
507 if (GET_CODE (op) == CONST
508 && GET_CODE (XEXP (op, 0)) == PLUS
509 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
510 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
511 && INT16_P (INTVAL (XEXP (XEXP (op, 0), 1))))
512 return SDATA_NAME_P (XSTR (XEXP (XEXP (op, 0), 0), 0));
513
514 return 0;
515}
516
517/* Return 1 if OP is a symbol that can use 24 bit addressing. */
518
519int
2b7972b0 520addr24_operand (op, int_mode)
8c5ca3b9 521 rtx op;
2b7972b0 522 int int_mode;
8c5ca3b9
DE
523{
524 if (GET_CODE (op) == LABEL_REF)
525 return TARGET_ADDR24;
526
527 if (GET_CODE (op) == SYMBOL_REF)
528 return (SMALL_NAME_P (XSTR (op, 0))
529 || (TARGET_ADDR24
630f5ae6
DE
530 && (CONSTANT_POOL_ADDRESS_P (op)
531 || LIT_NAME_P (XSTR (op, 0)))));
8c5ca3b9
DE
532
533 if (GET_CODE (op) == CONST
534 && GET_CODE (XEXP (op, 0)) == PLUS
535 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
536 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
537 && UINT24_P (INTVAL (XEXP (XEXP (op, 0), 1))))
538 {
539 rtx sym = XEXP (XEXP (op, 0), 0);
540 return (SMALL_NAME_P (XSTR (sym, 0))
541 || (TARGET_ADDR24
630f5ae6
DE
542 && (CONSTANT_POOL_ADDRESS_P (op)
543 || LIT_NAME_P (XSTR (op, 0)))));
8c5ca3b9
DE
544 }
545
546 return 0;
547}
548
549/* Return 1 if OP is a symbol that needs 32 bit addressing. */
550
551int
2b7972b0 552addr32_operand (op, int_mode)
8c5ca3b9 553 rtx op;
2b7972b0 554 int int_mode;
8c5ca3b9
DE
555{
556 if (GET_CODE (op) == LABEL_REF)
557 return TARGET_ADDR32;
558
559 if (GET_CODE (op) == SYMBOL_REF)
2b7972b0
MM
560 return (! addr24_operand (op, int_mode)
561 && ! small_data_operand (op, int_mode));
8c5ca3b9
DE
562
563 if (GET_CODE (op) == CONST
564 && GET_CODE (XEXP (op, 0)) == PLUS
565 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
566 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
567 {
2b7972b0
MM
568 return (! addr24_operand (op, int_mode)
569 && ! small_data_operand (op, int_mode));
8c5ca3b9
DE
570 }
571
572 return 0;
573}
574
575/* Return 1 if OP is a function that can be called with the `bl' insn. */
576
577int
2b7972b0 578call26_operand (op, int_mode)
8c5ca3b9 579 rtx op;
2b7972b0 580 int int_mode;
8c5ca3b9
DE
581{
582 if (GET_CODE (op) == SYMBOL_REF)
583 return ! LARGE_NAME_P (XSTR (op, 0));
584
585 return TARGET_CALL26;
586}
587
8c5ca3b9
DE
588/* Returns 1 if OP is an acceptable operand for seth/add3. */
589
590int
2b7972b0 591seth_add3_operand (op, int_mode)
8c5ca3b9 592 rtx op;
2b7972b0 593 int int_mode;
8c5ca3b9
DE
594{
595 if (GET_CODE (op) == SYMBOL_REF
596 || GET_CODE (op) == LABEL_REF)
597 return 1;
598
599 if (GET_CODE (op) == CONST
600 && GET_CODE (XEXP (op, 0)) == PLUS
601 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
602 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
603 && INT16_P (INTVAL (XEXP (XEXP (op, 0), 1))))
604 return 1;
605
606 return 0;
607}
608
8c5ca3b9
DE
609/* Return true if OP is a signed 16 bit immediate value
610 useful in comparisons. */
611
612int
2b7972b0 613cmp_int16_operand (op, int_mode)
8c5ca3b9 614 rtx op;
2b7972b0 615 int int_mode;
8c5ca3b9
DE
616{
617 if (GET_CODE (op) != CONST_INT)
618 return 0;
619 return CMP_INT16_P (INTVAL (op));
620}
621
622/* Return true if OP is an unsigned 16 bit immediate value. */
623
2b7972b0
MM
624int
625uint16_operand (op, int_mode)
8c5ca3b9 626 rtx op;
2b7972b0 627 int int_mode;
8c5ca3b9
DE
628{
629 if (GET_CODE (op) != CONST_INT)
630 return 0;
631 return UINT16_P (INTVAL (op));
632}
633
8c5ca3b9
DE
634/* Return true if OP is a register or signed 8 bit value. */
635
636int
2b7972b0 637reg_or_int16_operand (op, int_mode)
8c5ca3b9 638 rtx op;
2b7972b0 639 int int_mode;
8c5ca3b9 640{
2b7972b0
MM
641 enum machine_mode mode = (enum machine_mode)int_mode;
642
8c5ca3b9
DE
643 if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
644 return register_operand (op, mode);
645 if (GET_CODE (op) != CONST_INT)
646 return 0;
647 return INT16_P (INTVAL (op));
648}
649
2e076ddf 650/* Return true if OP is a register or an unsigned 16 bit value. */
8c5ca3b9
DE
651
652int
2b7972b0 653reg_or_uint16_operand (op, int_mode)
8c5ca3b9 654 rtx op;
2b7972b0 655 int int_mode;
8c5ca3b9 656{
2b7972b0
MM
657 enum machine_mode mode = (enum machine_mode)int_mode;
658
8c5ca3b9
DE
659 if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
660 return register_operand (op, mode);
661 if (GET_CODE (op) != CONST_INT)
662 return 0;
663 return UINT16_P (INTVAL (op));
664}
665
666/* Return true if OP is a register or signed 16 bit value for compares. */
667
668int
2b7972b0 669reg_or_cmp_int16_operand (op, int_mode)
8c5ca3b9 670 rtx op;
2b7972b0 671 int int_mode;
8c5ca3b9 672{
2b7972b0
MM
673 enum machine_mode mode = (enum machine_mode)int_mode;
674
8c5ca3b9
DE
675 if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
676 return register_operand (op, mode);
677 if (GET_CODE (op) != CONST_INT)
678 return 0;
679 return CMP_INT16_P (INTVAL (op));
680}
681
4d6c607f
DE
682/* Return true if OP is a const_int requiring two instructions to load. */
683
684int
2b7972b0 685two_insn_const_operand (op, int_mode)
4d6c607f 686 rtx op;
2b7972b0 687 int int_mode;
4d6c607f
DE
688{
689 if (GET_CODE (op) != CONST_INT)
690 return 0;
691 if (INT16_P (INTVAL (op))
692 || UINT24_P (INTVAL (op))
693 || UPPER16_P (INTVAL (op)))
694 return 0;
695 return 1;
696}
697
8c5ca3b9
DE
698/* Return true if OP is an acceptable argument for a single word
699 move source. */
700
701int
2b7972b0 702move_src_operand (op, int_mode)
8c5ca3b9 703 rtx op;
2b7972b0 704 int int_mode;
8c5ca3b9 705{
2b7972b0 706 enum machine_mode mode = (enum machine_mode)int_mode;
8c5ca3b9
DE
707 switch (GET_CODE (op))
708 {
709 case SYMBOL_REF :
710 case CONST :
2b7972b0 711 return addr24_operand (op, int_mode);
8c5ca3b9 712 case CONST_INT :
efbbf34f
DE
713 /* ??? We allow more cse opportunities if we only allow constants
714 loadable with one insn, and split the rest into two. The instances
715 where this would help should be rare and the current way is
716 simpler. */
8c5ca3b9
DE
717 return INT32_P (INTVAL (op));
718 case LABEL_REF :
719 return TARGET_ADDR24;
720 case CONST_DOUBLE :
721 if (mode == SFmode)
722 return 1;
723 else if (mode == SImode)
724 {
725 /* Large unsigned constants are represented as const_double's. */
726 unsigned HOST_WIDE_INT low, high;
727
728 low = CONST_DOUBLE_LOW (op);
729 high = CONST_DOUBLE_HIGH (op);
730 return high == 0 && low <= 0xffffffff;
731 }
732 else
733 return 0;
734 case REG :
735 return register_operand (op, mode);
736 case SUBREG :
737 /* (subreg (mem ...) ...) can occur here if the inner part was once a
738 pseudo-reg and is now a stack slot. */
739 if (GET_CODE (SUBREG_REG (op)) == MEM)
740 return address_operand (XEXP (SUBREG_REG (op), 0), mode);
741 else
742 return register_operand (op, mode);
743 case MEM :
744 return address_operand (XEXP (op, 0), mode);
745 default :
746 return 0;
747 }
748}
749
750/* Return true if OP is an acceptable argument for a double word
751 move source. */
752
753int
2b7972b0 754move_double_src_operand (op, int_mode)
8c5ca3b9 755 rtx op;
2b7972b0 756 int int_mode;
8c5ca3b9 757{
2b7972b0 758 enum machine_mode mode = (enum machine_mode)int_mode;
8c5ca3b9
DE
759 switch (GET_CODE (op))
760 {
761 case CONST_INT :
762 case CONST_DOUBLE :
5b8ae21f 763 return 1;
8c5ca3b9
DE
764 case REG :
765 return register_operand (op, mode);
766 case SUBREG :
767 /* (subreg (mem ...) ...) can occur here if the inner part was once a
768 pseudo-reg and is now a stack slot. */
769 if (GET_CODE (SUBREG_REG (op)) == MEM)
2b7972b0 770 return move_double_src_operand (SUBREG_REG (op), int_mode);
8c5ca3b9
DE
771 else
772 return register_operand (op, mode);
773 case MEM :
774 /* Disallow auto inc/dec for now. */
775 if (GET_CODE (XEXP (op, 0)) == PRE_DEC
776 || GET_CODE (XEXP (op, 0)) == PRE_INC)
777 return 0;
778 return address_operand (XEXP (op, 0), mode);
779 default :
780 return 0;
781 }
782}
783
784/* Return true if OP is an acceptable argument for a move destination. */
785
786int
2b7972b0 787move_dest_operand (op, int_mode)
8c5ca3b9 788 rtx op;
2b7972b0 789 int int_mode;
8c5ca3b9 790{
2b7972b0 791 enum machine_mode mode = (enum machine_mode)int_mode;
8c5ca3b9
DE
792 switch (GET_CODE (op))
793 {
794 case REG :
795 return register_operand (op, mode);
796 case SUBREG :
797 /* (subreg (mem ...) ...) can occur here if the inner part was once a
798 pseudo-reg and is now a stack slot. */
799 if (GET_CODE (SUBREG_REG (op)) == MEM)
800 return address_operand (XEXP (SUBREG_REG (op), 0), mode);
801 else
802 return register_operand (op, mode);
803 case MEM :
804 return address_operand (XEXP (op, 0), mode);
805 default :
806 return 0;
807 }
808}
809
810/* Return 1 if OP is a DImode const we want to handle inline.
811 This must match the code in the movdi pattern.
812 It is used by the 'G' CONST_DOUBLE_OK_FOR_LETTER. */
813
814int
815easy_di_const (op)
816 rtx op;
817{
818 rtx high_rtx, low_rtx;
819 HOST_WIDE_INT high, low;
820
821 split_double (op, &high_rtx, &low_rtx);
822 high = INTVAL (high_rtx);
823 low = INTVAL (low_rtx);
824 /* Pick constants loadable with 2 16 bit `ldi' insns. */
825 if (high >= -128 && high <= 127
826 && low >= -128 && low <= 127)
827 return 1;
828 return 0;
829}
830
831/* Return 1 if OP is a DFmode const we want to handle inline.
832 This must match the code in the movdf pattern.
833 It is used by the 'H' CONST_DOUBLE_OK_FOR_LETTER. */
834
835int
836easy_df_const (op)
837 rtx op;
838{
839 REAL_VALUE_TYPE r;
840 long l[2];
841
842 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
843 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
844 if (l[0] == 0 && l[1] == 0)
845 return 1;
846 if ((l[0] & 0xffff) == 0 && l[1] == 0)
847 return 1;
848 return 0;
849}
850
851/* Return 1 if OP is an EQ or NE comparison operator. */
852
853int
2b7972b0 854eqne_comparison_operator (op, int_mode)
8c5ca3b9 855 rtx op;
2b7972b0 856 int int_mode;
8c5ca3b9
DE
857{
858 enum rtx_code code = GET_CODE (op);
859
860 if (GET_RTX_CLASS (code) != '<')
861 return 0;
862 return (code == EQ || code == NE);
863}
864
865/* Return 1 if OP is a signed comparison operator. */
866
867int
2b7972b0 868signed_comparison_operator (op, int_mode)
8c5ca3b9 869 rtx op;
2b7972b0 870 int int_mode;
8c5ca3b9
DE
871{
872 enum rtx_code code = GET_CODE (op);
873
874 if (GET_RTX_CLASS (code) != '<')
875 return 0;
876 return (code == EQ || code == NE
877 || code == LT || code == LE || code == GT || code == GE);
878}
879
880/* Return 1 if OP is (mem (reg ...)).
881 This is used in insn length calcs. */
882
883int
2b7972b0 884memreg_operand (op, int_mode)
8c5ca3b9 885 rtx op;
2b7972b0 886 int int_mode;
8c5ca3b9
DE
887{
888 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG;
889}
2b7972b0
MM
890
891/* Return non-zero if the operand is an insn that is a small insn.
892 Allow const_int 0 as well, which is a placeholder for NOP slots. */
893
894int
895small_insn_p (op, int_mode)
896 rtx op;
897 int int_mode;
898{
899 if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
900 return 1;
901
902 if (GET_RTX_CLASS (GET_CODE (op)) != 'i')
903 return 0;
904
905 return get_attr_length (op) == 2;
906}
907
908/* Return non-zero if the operand is an insn that is a large insn. */
909
910int
911large_insn_p (op, int_mode)
912 rtx op;
913 int int_mode;
914{
915 if (GET_RTX_CLASS (GET_CODE (op)) != 'i')
916 return 0;
917
918 return get_attr_length (op) != 2;
919}
920
8c5ca3b9
DE
921\f
922/* Comparisons. */
923
924/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
925 return the mode to be used for the comparison. */
926
2b7972b0 927int
8c5ca3b9 928m32r_select_cc_mode (op, x, y)
2b7972b0 929 int op;
8c5ca3b9
DE
930 rtx x, y;
931{
51c10c4e 932 return (int)SImode;
8c5ca3b9
DE
933}
934
935/* X and Y are two things to compare using CODE. Emit the compare insn and
2b7972b0
MM
936 return the rtx for compare [arg0 of the if_then_else].
937 If need_compare is true then the comparison insn must be generated, rather
938 than being susummed into the following branch instruction. */
8c5ca3b9
DE
939
940rtx
c5c76735
JL
941gen_compare (code, x, y, need_compare)
942 enum rtx_code code;
943 rtx x, y;
944 int need_compare;
8c5ca3b9 945{
c5c76735
JL
946 enum machine_mode mode = SELECT_CC_MODE (code, x, y);
947 enum rtx_code compare_code, branch_code;
948 rtx cc_reg = gen_rtx_REG (mode, CARRY_REGNUM);
949 int swap_p = 0;
8c5ca3b9
DE
950
951 switch (code)
952 {
2e076ddf
NC
953 case EQ: compare_code = EQ; branch_code = NE; break;
954 case NE: compare_code = EQ; branch_code = EQ; break;
955 case LT: compare_code = LT; branch_code = NE; break;
956 case LE: compare_code = LT; branch_code = EQ; must_swap = 1; break;
957 case GT: compare_code = LT; branch_code = NE; must_swap = 1; break;
958 case GE: compare_code = LT; branch_code = EQ; break;
8c5ca3b9 959 case LTU: compare_code = LTU; branch_code = NE; break;
2e076ddf
NC
960 case LEU: compare_code = LTU; branch_code = EQ; must_swap = 1; break;
961 case GTU: compare_code = LTU; branch_code = NE; must_swap = 1; break;
8c5ca3b9
DE
962 case GEU: compare_code = LTU; branch_code = EQ; break;
963 }
964
2b7972b0
MM
965 if (need_compare)
966 {
967 switch (compare_code)
968 {
969 case EQ:
970 if (GET_CODE (y) == CONST_INT
971 && CMP_INT16_P (INTVAL (y)) /* reg equal to small const. */
972 && y != const0_rtx)
973 {
974 rtx tmp = gen_reg_rtx (SImode);
975
976 emit_insn (gen_cmp_ne_small_const_insn (tmp, x, y));
977 x = tmp;
978 y = const0_rtx;
979 }
980 else if (CONSTANT_P (y)) /* reg equal to const. */
981 {
982 rtx tmp = force_reg (GET_MODE (x), y);
983 y = tmp;
984 }
985
986 if (register_operand (y, SImode) /* reg equal to reg. */
987 || y == const0_rtx) /* req equal to zero. */
988 {
989 emit_insn (gen_cmp_eqsi_insn (x, y));
990
991 return gen_rtx (code, mode, cc_reg, const0_rtx);
992 }
993 break;
994
995 case LT:
996 if (register_operand (y, SImode)
997 || (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))
998 {
999 rtx tmp = gen_reg_rtx (SImode); /* reg compared to reg. */
1000
1001 switch (code)
1002 {
1003 case LT:
1004 emit_insn (gen_cmp_ltsi_insn (x, y));
1005 code = EQ;
1006 break;
1007 case LE:
1008 if (y == const0_rtx)
1009 tmp = const1_rtx;
1010 else
1011 emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));
1012 emit_insn (gen_cmp_ltsi_insn (x, tmp));
1013 code = EQ;
1014 break;
1015 case GT:
1016 if (GET_CODE (y) == CONST_INT)
1017 tmp = gen_rtx (PLUS, SImode, y, const1_rtx);
1018 else
1019 emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));
1020 emit_insn (gen_cmp_ltsi_insn (x, tmp));
1021 code = NE;
1022 break;
1023 case GE:
1024 emit_insn (gen_cmp_ltsi_insn (x, y));
1025 code = NE;
1026 break;
1027 default:
1028 abort();
1029 }
1030
1031 return gen_rtx (code, mode, cc_reg, const0_rtx);
1032 }
1033 break;
1034
1035 case LTU:
1036 if (register_operand (y, SImode)
1037 || (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))
1038 {
1039 rtx tmp = gen_reg_rtx (SImode); /* reg (unsigned) compared to reg. */
1040
1041 switch (code)
1042 {
1043 case LTU:
1044 emit_insn (gen_cmp_ltusi_insn (x, y));
1045 code = EQ;
1046 break;
1047 case LEU:
1048 if (y == const0_rtx)
1049 tmp = const1_rtx;
1050 else
1051 emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));
1052 emit_insn (gen_cmp_ltusi_insn (x, tmp));
1053 code = EQ;
1054 break;
1055 case GTU:
1056 if (GET_CODE (y) == CONST_INT)
1057 tmp = gen_rtx (PLUS, SImode, y, const1_rtx);
1058 else
1059 emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));
1060 emit_insn (gen_cmp_ltusi_insn (x, tmp));
1061 code = NE;
1062 break;
1063 case GEU:
1064 emit_insn (gen_cmp_ltusi_insn (x, y));
1065 code = NE;
1066 break;
1067 default:
1068 abort();
1069 }
1070
1071 return gen_rtx (code, mode, cc_reg, const0_rtx);
1072 }
1073 break;
1074
1075 default:
1076 abort();
1077 }
1078 }
1079 else
1080 if (! TARGET_OLD_COMPARE)
8c5ca3b9
DE
1081 {
1082 /* reg/reg equal comparison */
1083 if (compare_code == EQ
1084 && register_operand (y, SImode))
1085 return gen_rtx (code, mode, x, y);
2e076ddf 1086
8c5ca3b9
DE
1087 /* reg/zero signed comparison */
1088 if ((compare_code == EQ || compare_code == LT)
1089 && y == const0_rtx)
1090 return gen_rtx (code, mode, x, y);
2e076ddf 1091
8c5ca3b9
DE
1092 /* reg/smallconst equal comparison */
1093 if (compare_code == EQ
1094 && GET_CODE (y) == CONST_INT
1095 && CMP_INT16_P (INTVAL (y)))
1096 {
1097 rtx tmp = gen_reg_rtx (SImode);
1098 emit_insn (gen_cmp_ne_small_const_insn (tmp, x, y));
1099 return gen_rtx (code, mode, tmp, const0_rtx);
1100 }
2e076ddf 1101
8c5ca3b9
DE
1102 /* reg/const equal comparison */
1103 if (compare_code == EQ
1104 && CONSTANT_P (y))
1105 {
1106 rtx tmp = force_reg (GET_MODE (x), y);
1107 return gen_rtx (code, mode, x, tmp);
1108 }
1109 }
1110
2e076ddf 1111 if (CONSTANT_P (y))
8c5ca3b9 1112 {
2e076ddf 1113 if (must_swap)
8c5ca3b9 1114 y = force_reg (GET_MODE (x), y);
2e076ddf
NC
1115 else
1116 {
1117 int ok_const =
1118 (code == LTU || code == LEU || code == GTU || code == GEU)
1119 ? uint16_operand (y, GET_MODE (y))
1120 : reg_or_cmp_int16_operand (y, GET_MODE (y));
1121
1122 if (! ok_const)
1123 y = force_reg (GET_MODE (x), y);
1124 }
8c5ca3b9
DE
1125 }
1126
1127 switch (compare_code)
1128 {
1129 case EQ :
2e076ddf 1130 emit_insn (gen_cmp_eqsi_insn (must_swap ? y : x, must_swap ? x : y));
8c5ca3b9
DE
1131 break;
1132 case LT :
2e076ddf 1133 emit_insn (gen_cmp_ltsi_insn (must_swap ? y : x, must_swap ? x : y));
8c5ca3b9
DE
1134 break;
1135 case LTU :
2e076ddf 1136 emit_insn (gen_cmp_ltusi_insn (must_swap ? y : x, must_swap ? x : y));
8c5ca3b9
DE
1137 break;
1138 }
1139
1140 return gen_rtx (branch_code, VOIDmode, cc_reg, CONST0_RTX (mode));
1141}
5b8ae21f
MM
1142\f
1143/* Split a 2 word move (DI or DF) into component parts. */
1144
1145rtx
1146gen_split_move_double (operands)
1147 rtx operands[];
1148{
1149 enum machine_mode mode = GET_MODE (operands[0]);
1150 rtx dest = operands[0];
1151 rtx src = operands[1];
1152 rtx val;
1153
ca3bf2b5
JW
1154 /* We might have (SUBREG (MEM)) here, so just get rid of the
1155 subregs to make this code simpler. It is safe to call
1156 alter_subreg any time after reload. */
1157 if (GET_CODE (dest) == SUBREG)
1158 dest = alter_subreg (dest);
1159 if (GET_CODE (src) == SUBREG)
1160 src = alter_subreg (src);
1161
5b8ae21f 1162 start_sequence ();
ca3bf2b5 1163 if (GET_CODE (dest) == REG)
5b8ae21f 1164 {
ca3bf2b5
JW
1165 int dregno = REGNO (dest);
1166
5b8ae21f 1167 /* reg = reg */
ca3bf2b5 1168 if (GET_CODE (src) == REG)
5b8ae21f 1169 {
ca3bf2b5
JW
1170 int sregno = REGNO (src);
1171
1172 int reverse = (dregno == sregno + 1);
1173
5b8ae21f
MM
1174 /* We normally copy the low-numbered register first. However, if
1175 the first register operand 0 is the same as the second register of
1176 operand 1, we must copy in the opposite order. */
5b8ae21f
MM
1177 emit_insn (gen_rtx_SET (VOIDmode,
1178 operand_subword (dest, reverse, TRUE, mode),
1179 operand_subword (src, reverse, TRUE, mode)));
1180
1181 emit_insn (gen_rtx_SET (VOIDmode,
1182 operand_subword (dest, !reverse, TRUE, mode),
1183 operand_subword (src, !reverse, TRUE, mode)));
1184 }
1185
1186 /* reg = constant */
1187 else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
1188 {
1189 rtx words[2];
1190 split_double (src, &words[0], &words[1]);
1191 emit_insn (gen_rtx_SET (VOIDmode,
1192 operand_subword (dest, 0, TRUE, mode),
1193 words[0]));
1194
1195 emit_insn (gen_rtx_SET (VOIDmode,
1196 operand_subword (dest, 1, TRUE, mode),
1197 words[1]));
1198 }
1199
1200 /* reg = mem */
1201 else if (GET_CODE (src) == MEM)
1202 {
1203 /* If the high-address word is used in the address, we must load it
1204 last. Otherwise, load it first. */
1205 rtx addr = XEXP (src, 0);
ca3bf2b5 1206 int reverse = (refers_to_regno_p (dregno, dregno+1, addr, 0) != 0);
5b8ae21f
MM
1207
1208 /* We used to optimize loads from single registers as
1209
1210 ld r1,r3+; ld r2,r3
1211
1212 if r3 were not used subsequently. However, the REG_NOTES aren't
1213 propigated correctly by the reload phase, and it can cause bad
1214 code to be generated. We could still try:
1215
1216 ld r1,r3+; ld r2,r3; addi r3,-4
1217
1218 which saves 2 bytes and doesn't force longword alignment. */
1219 emit_insn (gen_rtx_SET (VOIDmode,
1220 operand_subword (dest, reverse, TRUE, mode),
1221 change_address (src, SImode,
1222 plus_constant (addr,
1223 reverse * UNITS_PER_WORD))));
1224
1225 emit_insn (gen_rtx_SET (VOIDmode,
1226 operand_subword (dest, !reverse, TRUE, mode),
1227 change_address (src, SImode,
1228 plus_constant (addr,
1229 (!reverse) * UNITS_PER_WORD))));
1230 }
1231
1232 else
1233 abort ();
1234 }
1235
1236 /* mem = reg */
1237 /* We used to optimize loads from single registers as
1238
1239 st r1,r3; st r2,+r3
1240
1241 if r3 were not used subsequently. However, the REG_NOTES aren't
1242 propigated correctly by the reload phase, and it can cause bad
1243 code to be generated. We could still try:
1244
1245 st r1,r3; st r2,+r3; addi r3,-4
1246
1247 which saves 2 bytes and doesn't force longword alignment. */
ca3bf2b5 1248 else if (GET_CODE (dest) == MEM && GET_CODE (src) == REG)
5b8ae21f
MM
1249 {
1250 rtx addr = XEXP (dest, 0);
1251
1252 emit_insn (gen_rtx_SET (VOIDmode,
1253 change_address (dest, SImode, addr),
1254 operand_subword (src, 0, TRUE, mode)));
1255
1256 emit_insn (gen_rtx_SET (VOIDmode,
1257 change_address (dest, SImode,
1258 plus_constant (addr, UNITS_PER_WORD)),
1259 operand_subword (src, 1, TRUE, mode)));
1260 }
1261
1262 else
1263 abort ();
1264
1265 val = gen_sequence ();
1266 end_sequence ();
1267 return val;
1268}
1269
8c5ca3b9
DE
1270\f
1271/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro. */
1272
1273int
2b7972b0 1274function_arg_partial_nregs (cum, int_mode, type, named)
8c5ca3b9 1275 CUMULATIVE_ARGS *cum;
2b7972b0 1276 int int_mode;
8c5ca3b9
DE
1277 tree type;
1278 int named;
1279{
2b7972b0 1280 enum machine_mode mode = (enum machine_mode)int_mode;
8c5ca3b9
DE
1281 int ret;
1282 int size = (((mode == BLKmode && type)
1283 ? int_size_in_bytes (type)
1284 : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1285
1286 if (*cum >= M32R_MAX_PARM_REGS)
1287 ret = 0;
1288 else if (*cum + size > M32R_MAX_PARM_REGS)
1289 ret = (*cum + size) - M32R_MAX_PARM_REGS;
1290 else
1291 ret = 0;
1292
1293 return ret;
1294}
1295
1296/* Do any needed setup for a variadic function. For the M32R, we must
1297 create a register parameter block, and then copy any anonymous arguments
1298 in registers to memory.
1299
1300 CUM has not been updated for the last named argument which has type TYPE
1301 and mode MODE, and we rely on this fact. */
1302
1303void
2b7972b0 1304m32r_setup_incoming_varargs (cum, int_mode, type, pretend_size, no_rtl)
8c5ca3b9 1305 CUMULATIVE_ARGS *cum;
2b7972b0 1306 int int_mode;
8c5ca3b9
DE
1307 tree type;
1308 int *pretend_size;
1309 int no_rtl;
1310{
2b7972b0 1311 enum machine_mode mode = (enum machine_mode)int_mode;
8c5ca3b9
DE
1312 int first_anon_arg;
1313
1314 if (no_rtl)
1315 return;
1316
1317 /* All BLKmode values are passed by reference. */
1318 if (mode == BLKmode)
1319 abort ();
1320
1321 /* We must treat `__builtin_va_alist' as an anonymous arg. */
1322 if (current_function_varargs)
1323 first_anon_arg = *cum;
1324 else
1325 first_anon_arg = (ROUND_ADVANCE_CUM (*cum, mode, type)
1326 + ROUND_ADVANCE_ARG (mode, type));
1327
1328 if (first_anon_arg < M32R_MAX_PARM_REGS)
1329 {
1330 /* Note that first_reg_offset < M32R_MAX_PARM_REGS. */
1331 int first_reg_offset = first_anon_arg;
1332 /* Size in words to "pretend" allocate. */
1333 int size = M32R_MAX_PARM_REGS - first_reg_offset;
1334 rtx regblock;
1335
c5c76735
JL
1336 regblock = gen_rtx_MEM (BLKmode,
1337 plus_constant (arg_pointer_rtx,
1338 FIRST_PARM_OFFSET (0)));
40cae311 1339 MEM_ALIAS_SET (regblock) = get_varargs_alias_set ();
8c5ca3b9
DE
1340 move_block_from_reg (first_reg_offset, regblock,
1341 size, size * UNITS_PER_WORD);
1342
1343 *pretend_size = (size * UNITS_PER_WORD);
1344 }
1345}
40cae311
RH
1346
1347/* Implement `va_arg'. */
1348
1349rtx
1350m32r_va_arg (valist, type)
1351 tree valist, type;
1352{
1353 HOST_WIDE_INT size, rsize;
1354 tree t;
1355 rtx addr_rtx;
1356
1357 size = int_size_in_bytes (type);
1358 rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
1359
1360 if (size > 8)
1361 {
1362 tree type_ptr, type_ptr_ptr;
1363
1364 /* Pass by reference. */
1365
1366 type_ptr = build_pointer_type (type);
1367 type_ptr_ptr = build_pointer_type (type_ptr);
1368
1369 t = build (POSTINCREMENT_EXPR, va_list_type_node, valist,
1370 build_int_2 (UNITS_PER_WORD, 0));
1371 TREE_SIDE_EFFECTS (t) = 1;
1372 t = build1 (NOP_EXPR, type_ptr_ptr, t);
1373 TREE_SIDE_EFFECTS (t) = 1;
1374 t = build1 (INDIRECT_REF, type_ptr, t);
1375
1376 addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
1377 }
1378 else
1379 {
1380 /* Pass by value. */
1381
1382 if (size < UNITS_PER_WORD)
1383 {
1384 /* Care for bigendian correction on the aligned address. */
1385 t = build (PLUS_EXPR, ptr_type_node, valist,
1386 build_int_2 (rsize - size, 0));
1387 addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
1388 addr_rtx = copy_to_reg (addr_rtx);
1389
1390 /* Increment AP. */
1391 t = build (PLUS_EXPR, va_list_type_node, valist,
1392 build_int_2 (rsize, 0));
1393 t = build (MODIFY_EXPR, va_list_type_node, valist, t);
1394 TREE_SIDE_EFFECTS (t) = 1;
1395 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1396 }
1397 else
1398 {
1399 t = build (POSTINCREMENT_EXPR, va_list_type_node, valist,
1400 build_int_2 (rsize, 0));
1401 TREE_SIDE_EFFECTS (t) = 1;
1402 addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
1403 }
1404 }
1405
1406 return addr_rtx;
1407}
8c5ca3b9
DE
1408\f
1409/* Cost functions. */
1410
1411/* Provide the costs of an addressing mode that contains ADDR.
1412 If ADDR is not a valid address, its cost is irrelevant.
1413
1414 This function is trivial at the moment. This code doesn't live
1415 in m32r.h so it's easy to experiment. */
1416
1417int
1418m32r_address_cost (addr)
1419 rtx addr;
1420{
1421 return 1;
1422}
1423\f
1424/* Type of function DECL.
1425
1426 The result is cached. To reset the cache at the end of a function,
1427 call with DECL = NULL_TREE. */
1428
1429enum m32r_function_type
1430m32r_compute_function_type (decl)
1431 tree decl;
1432{
1433 /* Cached value. */
1434 static enum m32r_function_type fn_type = M32R_FUNCTION_UNKNOWN;
1435 /* Last function we were called for. */
1436 static tree last_fn = NULL_TREE;
1437
1438 /* Resetting the cached value? */
1439 if (decl == NULL_TREE)
1440 {
1441 fn_type = M32R_FUNCTION_UNKNOWN;
1442 last_fn = NULL_TREE;
1443 return fn_type;
1444 }
1445
1446 if (decl == last_fn && fn_type != M32R_FUNCTION_UNKNOWN)
1447 return fn_type;
1448
1449 /* Compute function type. */
1450 fn_type = (lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (current_function_decl)) != NULL_TREE
1451 ? M32R_FUNCTION_INTERRUPT
1452 : M32R_FUNCTION_NORMAL);
1453
1454 last_fn = decl;
1455 return fn_type;
1456}
1457\f/* Function prologue/epilogue handlers. */
1458
1459/* M32R stack frames look like:
1460
1461 Before call After call
1462 +-----------------------+ +-----------------------+
1463 | | | |
1464 high | local variables, | | local variables, |
1465 mem | reg save area, etc. | | reg save area, etc. |
1466 | | | |
1467 +-----------------------+ +-----------------------+
1468 | | | |
1469 | arguments on stack. | | arguments on stack. |
1470 | | | |
1471 SP+0->+-----------------------+ +-----------------------+
1472 | reg parm save area, |
1473 | only created for |
1474 | variable argument |
1475 | functions |
1476 +-----------------------+
1477 | previous frame ptr |
1478 +-----------------------+
1479 | |
1480 | register save area |
1481 | |
1482 +-----------------------+
1483 | return address |
1484 +-----------------------+
1485 | |
1486 | local variables |
1487 | |
1488 +-----------------------+
1489 | |
1490 | alloca allocations |
1491 | |
1492 +-----------------------+
1493 | |
1494 low | arguments on stack |
1495 memory | |
1496 SP+0->+-----------------------+
1497
1498Notes:
14991) The "reg parm save area" does not exist for non variable argument fns.
15002) The "reg parm save area" can be eliminated completely if we saved regs
1501 containing anonymous args separately but that complicates things too
1502 much (so it's not done).
15033) The return address is saved after the register save area so as to have as
1504 many insns as possible between the restoration of `lr' and the `jmp lr'.
1505*/
1506
1507/* Structure to be filled in by m32r_compute_frame_size with register
1508 save masks, and offsets for the current function. */
1509struct m32r_frame_info
1510{
1511 unsigned int total_size; /* # bytes that the entire frame takes up */
1512 unsigned int extra_size; /* # bytes of extra stuff */
1513 unsigned int pretend_size; /* # bytes we push and pretend caller did */
1514 unsigned int args_size; /* # bytes that outgoing arguments take up */
1515 unsigned int reg_size; /* # bytes needed to store regs */
1516 unsigned int var_size; /* # bytes that variables take up */
1517 unsigned int gmask; /* mask of saved gp registers */
1518 unsigned int save_fp; /* nonzero if fp must be saved */
1519 unsigned int save_lr; /* nonzero if lr (return addr) must be saved */
1520 int initialized; /* nonzero if frame size already calculated */
1521};
1522
1523/* Current frame information calculated by m32r_compute_frame_size. */
1524static struct m32r_frame_info current_frame_info;
1525
1526/* Zero structure to initialize current_frame_info. */
1527static struct m32r_frame_info zero_frame_info;
1528
1529#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
1530#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
1531
1532/* Tell prologue and epilogue if register REGNO should be saved / restored.
1533 The return address and frame pointer are treated separately.
1534 Don't consider them here. */
1535#define MUST_SAVE_REGISTER(regno, interrupt_p) \
1536((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
1537 && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
1538
1539#define MUST_SAVE_FRAME_POINTER (regs_ever_live[FRAME_POINTER_REGNUM])
5b8ae21f 1540#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM] || profile_flag)
8c5ca3b9 1541
2b7972b0
MM
1542#define SHORT_INSN_SIZE 2 /* size of small instructions */
1543#define LONG_INSN_SIZE 4 /* size of long instructions */
1544
8c5ca3b9
DE
1545/* Return the bytes needed to compute the frame pointer from the current
1546 stack pointer.
1547
1548 SIZE is the size needed for local variables. */
1549
1550unsigned int
1551m32r_compute_frame_size (size)
1552 int size; /* # of var. bytes allocated. */
1553{
1554 int regno;
1555 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
5b8ae21f 1556 unsigned int reg_size, frame_size;
8c5ca3b9
DE
1557 unsigned int gmask;
1558 enum m32r_function_type fn_type;
1559 int interrupt_p;
1560
1561 var_size = M32R_STACK_ALIGN (size);
1562 args_size = M32R_STACK_ALIGN (current_function_outgoing_args_size);
1563 pretend_size = current_function_pretend_args_size;
1564 extra_size = FIRST_PARM_OFFSET (0);
1565 total_size = extra_size + pretend_size + args_size + var_size;
1566 reg_size = 0;
1567 gmask = 0;
1568
1569 /* See if this is an interrupt handler. Call used registers must be saved
1570 for them too. */
1571 fn_type = m32r_compute_function_type (current_function_decl);
1572 interrupt_p = M32R_INTERRUPT_P (fn_type);
1573
1574 /* Calculate space needed for registers. */
1575
1576 for (regno = 0; regno < M32R_MAX_INT_REGS; regno++)
1577 {
1578 if (MUST_SAVE_REGISTER (regno, interrupt_p))
1579 {
1580 reg_size += UNITS_PER_WORD;
1581 gmask |= 1 << regno;
1582 }
1583 }
1584
1585 current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
1586 current_frame_info.save_lr = MUST_SAVE_RETURN_ADDR;
1587
1588 reg_size += ((current_frame_info.save_fp + current_frame_info.save_lr)
1589 * UNITS_PER_WORD);
1590 total_size += reg_size;
1591
efbbf34f 1592 /* ??? Not sure this is necessary, and I don't think the epilogue
8c5ca3b9
DE
1593 handler will do the right thing if this changes total_size. */
1594 total_size = M32R_STACK_ALIGN (total_size);
1595
2b7972b0
MM
1596 frame_size = total_size - (pretend_size + reg_size);
1597
8c5ca3b9
DE
1598 /* Save computed information. */
1599 current_frame_info.total_size = total_size;
1600 current_frame_info.extra_size = extra_size;
1601 current_frame_info.pretend_size = pretend_size;
1602 current_frame_info.var_size = var_size;
1603 current_frame_info.args_size = args_size;
1604 current_frame_info.reg_size = reg_size;
1605 current_frame_info.gmask = gmask;
1606 current_frame_info.initialized = reload_completed;
1607
1608 /* Ok, we're done. */
1609 return total_size;
1610}
1611\f
2b7972b0
MM
1612/* When the `length' insn attribute is used, this macro specifies the
1613 value to be assigned to the address of the first insn in a
1614 function. If not specified, 0 is used. */
1615
1616int
1617m32r_first_insn_address ()
1618{
1619 if (! current_frame_info.initialized)
1620 m32r_compute_frame_size (get_frame_size ());
1621
5b8ae21f 1622 return 0;
2b7972b0
MM
1623}
1624\f
5b8ae21f 1625/* Expand the m32r prologue as a series of insns. */
8c5ca3b9
DE
1626
1627void
5b8ae21f 1628m32r_expand_prologue ()
8c5ca3b9
DE
1629{
1630 int regno;
5b8ae21f 1631 int frame_size;
8c5ca3b9 1632 unsigned int gmask = current_frame_info.gmask;
8c5ca3b9 1633
5b8ae21f
MM
1634 if (! current_frame_info.initialized)
1635 m32r_compute_frame_size (get_frame_size ());
2b7972b0 1636
5b8ae21f 1637 gmask = current_frame_info.gmask;
8c5ca3b9
DE
1638
1639 /* These cases shouldn't happen. Catch them now. */
5b8ae21f 1640 if (current_frame_info.total_size == 0 && gmask)
8c5ca3b9
DE
1641 abort ();
1642
8c5ca3b9
DE
1643 /* Allocate space for register arguments if this is a variadic function. */
1644 if (current_frame_info.pretend_size != 0)
737e7965
JW
1645 {
1646 /* Use a HOST_WIDE_INT temporary, since negating an unsigned int gives
1647 the wrong result on a 64-bit host. */
1648 HOST_WIDE_INT pretend_size = current_frame_info.pretend_size;
1649 emit_insn (gen_addsi3 (stack_pointer_rtx,
1650 stack_pointer_rtx,
1651 GEN_INT (-pretend_size)));
1652 }
8c5ca3b9
DE
1653
1654 /* Save any registers we need to and set up fp. */
1655
1656 if (current_frame_info.save_fp)
5b8ae21f 1657 emit_insn (gen_movsi_push (stack_pointer_rtx, frame_pointer_rtx));
8c5ca3b9
DE
1658
1659 gmask &= ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK);
1660
1661 /* Save any needed call-saved regs (and call-used if this is an
1662 interrupt handler). */
1663 for (regno = 0; regno <= M32R_MAX_INT_REGS; ++regno)
1664 {
1665 if ((gmask & (1 << regno)) != 0)
5b8ae21f
MM
1666 emit_insn (gen_movsi_push (stack_pointer_rtx,
1667 gen_rtx_REG (Pmode, regno)));
8c5ca3b9
DE
1668 }
1669
1670 if (current_frame_info.save_lr)
5b8ae21f
MM
1671 emit_insn (gen_movsi_push (stack_pointer_rtx,
1672 gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)));
8c5ca3b9
DE
1673
1674 /* Allocate the stack frame. */
5b8ae21f
MM
1675 frame_size = (current_frame_info.total_size
1676 - (current_frame_info.pretend_size
1677 + current_frame_info.reg_size));
1678
8c5ca3b9
DE
1679 if (frame_size == 0)
1680 ; /* nothing to do */
8c5ca3b9 1681 else if (frame_size <= 32768)
5b8ae21f
MM
1682 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1683 GEN_INT (-frame_size)));
8c5ca3b9 1684 else
5b8ae21f
MM
1685 {
1686 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
1687 emit_insn (gen_movsi (tmp, GEN_INT (frame_size)));
1688 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
1689 }
8c5ca3b9
DE
1690
1691 if (frame_pointer_needed)
5b8ae21f
MM
1692 emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
1693
1694 if (profile_flag || profile_block_flag)
1695 emit_insn (gen_blockage ());
1696}
1697
1698\f
1699/* Set up the stack and frame pointer (if desired) for the function.
1700 Note, if this is changed, you need to mirror the changes in
1701 m32r_compute_frame_size which calculates the prolog size. */
1702
1703void
1704m32r_output_function_prologue (file, size)
1705 FILE * file;
1706 int size;
1707{
1708 enum m32r_function_type fn_type = m32r_compute_function_type (current_function_decl);
1709
1710 /* If this is an interrupt handler, mark it as such. */
1711 if (M32R_INTERRUPT_P (fn_type))
1712 {
1713 fprintf (file, "\t%s interrupt handler\n",
1714 ASM_COMMENT_START);
1715 }
1716
1717 if (! current_frame_info.initialized)
1718 m32r_compute_frame_size (size);
8c5ca3b9 1719
5b8ae21f
MM
1720 /* This is only for the human reader. */
1721 fprintf (file,
1722 "\t%s PROLOGUE, vars= %d, regs= %d, args= %d, extra= %d\n",
1723 ASM_COMMENT_START,
1724 current_frame_info.var_size,
1725 current_frame_info.reg_size / 4,
1726 current_frame_info.args_size,
1727 current_frame_info.extra_size);
8c5ca3b9
DE
1728}
1729\f
1730/* Do any necessary cleanup after a function to restore stack, frame,
1731 and regs. */
1732
1733void
1734m32r_output_function_epilogue (file, size)
2e076ddf
NC
1735 FILE * file;
1736 int size;
8c5ca3b9
DE
1737{
1738 int regno;
1739 int noepilogue = FALSE;
1740 int total_size;
1741 enum m32r_function_type fn_type = m32r_compute_function_type (current_function_decl);
1742
1743 /* This is only for the human reader. */
1744 fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
1745
1746 if (!current_frame_info.initialized)
1747 abort ();
1748 total_size = current_frame_info.total_size;
1749
1750 if (total_size == 0)
1751 {
1752 rtx insn = get_last_insn ();
1753
1754 /* If the last insn was a BARRIER, we don't have to write any code
1755 because a jump (aka return) was put there. */
1756 if (GET_CODE (insn) == NOTE)
1757 insn = prev_nonnote_insn (insn);
1758 if (insn && GET_CODE (insn) == BARRIER)
1759 noepilogue = TRUE;
1760 }
1761
1762 if (!noepilogue)
1763 {
1764 unsigned int pretend_size = current_frame_info.pretend_size;
1765 unsigned int frame_size = total_size - pretend_size;
1766 unsigned int var_size = current_frame_info.var_size;
1767 unsigned int args_size = current_frame_info.args_size;
1768 unsigned int gmask = current_frame_info.gmask;
1769 int can_trust_sp_p = !current_function_calls_alloca;
2e076ddf
NC
1770 char * sp_str = reg_names[STACK_POINTER_REGNUM];
1771 char * fp_str = reg_names[FRAME_POINTER_REGNUM];
8c5ca3b9
DE
1772
1773 /* The first thing to do is point the sp at the bottom of the register
1774 save area. */
1775 if (can_trust_sp_p)
1776 {
1777 unsigned int reg_offset = var_size + args_size;
1778 if (reg_offset == 0)
1779 ; /* nothing to do */
630f5ae6
DE
1780 else if (reg_offset < 128)
1781 fprintf (file, "\taddi %s,%s%d\n",
1782 sp_str, IMMEDIATE_PREFIX, reg_offset);
8c5ca3b9 1783 else if (reg_offset < 32768)
630f5ae6
DE
1784 fprintf (file, "\tadd3 %s,%s,%s%d\n",
1785 sp_str, sp_str, IMMEDIATE_PREFIX, reg_offset);
8c5ca3b9 1786 else
630f5ae6
DE
1787 fprintf (file, "\tld24 %s,%s%d\n\tadd %s,%s\n",
1788 reg_names[PROLOGUE_TMP_REGNUM],
1789 IMMEDIATE_PREFIX, reg_offset,
8c5ca3b9
DE
1790 sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
1791 }
1792 else if (frame_pointer_needed)
1793 {
1794 unsigned int reg_offset = var_size + args_size;
1795 if (reg_offset == 0)
1796 fprintf (file, "\tmv %s,%s\n", sp_str, fp_str);
1797 else if (reg_offset < 32768)
630f5ae6
DE
1798 fprintf (file, "\tadd3 %s,%s,%s%d\n",
1799 sp_str, fp_str, IMMEDIATE_PREFIX, reg_offset);
8c5ca3b9 1800 else
630f5ae6
DE
1801 fprintf (file, "\tld24 %s,%s%d\n\tadd %s,%s\n",
1802 reg_names[PROLOGUE_TMP_REGNUM],
1803 IMMEDIATE_PREFIX, reg_offset,
8c5ca3b9
DE
1804 sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
1805 }
1806 else
1807 abort ();
1808
1809 if (current_frame_info.save_lr)
1810 fprintf (file, "\tpop %s\n", reg_names[RETURN_ADDR_REGNUM]);
1811
1812 /* Restore any saved registers, in reverse order of course. */
1813 gmask &= ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK);
1814 for (regno = M32R_MAX_INT_REGS - 1; regno >= 0; --regno)
1815 {
1816 if ((gmask & (1L << regno)) != 0)
1817 fprintf (file, "\tpop %s\n", reg_names[regno]);
1818 }
1819
1820 if (current_frame_info.save_fp)
1821 fprintf (file, "\tpop %s\n", fp_str);
1822
1823 /* Remove varargs area if present. */
8c5ca3b9 1824 if (current_frame_info.pretend_size != 0)
630f5ae6
DE
1825 fprintf (file, "\taddi %s,%s%d\n",
1826 sp_str, IMMEDIATE_PREFIX, current_frame_info.pretend_size);
8c5ca3b9
DE
1827
1828 /* Emit the return instruction. */
1829 if (M32R_INTERRUPT_P (fn_type))
1830 fprintf (file, "\trte\n");
1831 else
1832 fprintf (file, "\tjmp %s\n", reg_names[RETURN_ADDR_REGNUM]);
1833 }
1834
1835#if 0 /* no longer needed */
1836 /* Ensure the function cleanly ends on a 32 bit boundary. */
1837 fprintf (file, "\t.fillinsn\n");
1838#endif
1839
1840 /* Reset state info for each function. */
1841 current_frame_info = zero_frame_info;
1842 m32r_compute_function_type (NULL_TREE);
1843}
1844\f
1845/* PIC */
1846
1847/* Emit special PIC prologues and epilogues. */
1848
1849void
1850m32r_finalize_pic ()
1851{
1852 /* nothing to do */
1853}
1854\f
1855/* Nested function support. */
1856
1857/* Emit RTL insns to initialize the variable parts of a trampoline.
1858 FNADDR is an RTX for the address of the function's pure code.
1859 CXT is an RTX for the static chain value for the function. */
1860
1861void
1862m32r_initialize_trampoline (tramp, fnaddr, cxt)
1863 rtx tramp, fnaddr, cxt;
1864{
1865}
1866\f
1867/* Set the cpu type and print out other fancy things,
1868 at the top of the file. */
1869
1870void
1871m32r_asm_file_start (file)
2e076ddf 1872 FILE * file;
8c5ca3b9
DE
1873{
1874 if (flag_verbose_asm)
1875 fprintf (file, "%s M32R/D special options: -G %d\n",
1876 ASM_COMMENT_START, g_switch_value);
1877}
1878\f
1879/* Print operand X (an rtx) in assembler syntax to file FILE.
1880 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
1881 For `%' followed by punctuation, CODE is the punctuation and X is null. */
1882
1883void
1884m32r_print_operand (file, x, code)
2e076ddf
NC
1885 FILE * file;
1886 rtx x;
1887 int code;
8c5ca3b9 1888{
5b8ae21f
MM
1889 rtx addr;
1890
8c5ca3b9
DE
1891 switch (code)
1892 {
d2a73f8e
NC
1893 /* The 's' and 'p' codes are used by output_block_move() to
1894 indicate post-increment 's'tores and 'p're-increment loads. */
1895 case 's':
1896 if (GET_CODE (x) == REG)
1897 fprintf (file, "@+%s", reg_names [REGNO (x)]);
1898 else
1899 output_operand_lossage ("invalid operand to %s code");
1900 return;
1901
1902 case 'p':
1903 if (GET_CODE (x) == REG)
1904 fprintf (file, "@%s+", reg_names [REGNO (x)]);
1905 else
1906 output_operand_lossage ("invalid operand to %p code");
1907 return;
1908
8c5ca3b9
DE
1909 case 'R' :
1910 /* Write second word of DImode or DFmode reference,
1911 register or memory. */
1912 if (GET_CODE (x) == REG)
1913 fputs (reg_names[REGNO (x)+1], file);
1914 else if (GET_CODE (x) == MEM)
1915 {
1916 fprintf (file, "@(");
1917 /* Handle possible auto-increment. Since it is pre-increment and
1918 we have already done it, we can just use an offset of four. */
1919 /* ??? This is taken from rs6000.c I think. I don't think it is
1920 currently necessary, but keep it around. */
1921 if (GET_CODE (XEXP (x, 0)) == PRE_INC
1922 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
1923 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
1924 else
1925 output_address (plus_constant (XEXP (x, 0), 4));
1926 fputc (')', file);
1927 }
1928 else
1929 output_operand_lossage ("invalid operand to %R code");
1930 return;
1931
1932 case 'H' : /* High word */
1933 case 'L' : /* Low word */
1934 if (GET_CODE (x) == REG)
1935 {
1936 /* L = least significant word, H = most significant word */
1937 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
1938 fputs (reg_names[REGNO (x)], file);
1939 else
1940 fputs (reg_names[REGNO (x)+1], file);
1941 }
1942 else if (GET_CODE (x) == CONST_INT
1943 || GET_CODE (x) == CONST_DOUBLE)
1944 {
1945 rtx first, second;
1946
1947 split_double (x, &first, &second);
d2a73f8e 1948 fprintf (file, "0x%08x",
8c5ca3b9
DE
1949 code == 'L' ? INTVAL (first) : INTVAL (second));
1950 }
1951 else
1952 output_operand_lossage ("invalid operand to %H/%L code");
1953 return;
1954
1955 case 'A' :
1956 {
1957 REAL_VALUE_TYPE d;
1958 char str[30];
1959
1960 if (GET_CODE (x) != CONST_DOUBLE
1961 || GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT)
1962 abort ();
1963 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1964 REAL_VALUE_TO_DECIMAL (d, "%.20e", str);
1965 fprintf (file, "%s", str);
1966 return;
1967 }
1968
1969 case 'B' : /* Bottom half */
1970 case 'T' : /* Top half */
1971 /* Output the argument to a `seth' insn (sets the Top half-word).
1972 For constants output arguments to a seth/or3 pair to set Top and
1973 Bottom halves. For symbols output arguments to a seth/add3 pair to
1974 set Top and Bottom halves. The difference exists because for
1975 constants seth/or3 is more readable but for symbols we need to use
1976 the same scheme as `ld' and `st' insns (16 bit addend is signed). */
1977 switch (GET_CODE (x))
1978 {
1979 case CONST_INT :
1980 case CONST_DOUBLE :
1981 {
1982 rtx first, second;
1983
1984 split_double (x, &first, &second);
1985 x = WORDS_BIG_ENDIAN ? second : first;
1986 fprintf (file,
1987#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
1988 "0x%x",
1989#else
1990 "0x%lx",
1991#endif
1992 (code == 'B'
1993 ? INTVAL (x) & 0xffff
1994 : (INTVAL (x) >> 16) & 0xffff));
1995 }
1996 return;
1997 case CONST :
1998 case SYMBOL_REF :
1999 if (code == 'B'
2000 && small_data_operand (x, VOIDmode))
2001 {
2002 fputs ("sda(", file);
2003 output_addr_const (file, x);
2004 fputc (')', file);
2005 return;
2006 }
2007 /* fall through */
2008 case LABEL_REF :
2009 fputs (code == 'T' ? "shigh(" : "low(", file);
2010 output_addr_const (file, x);
2011 fputc (')', file);
2012 return;
2013 default :
2014 output_operand_lossage ("invalid operand to %T/%B code");
2015 return;
2016 }
2017 break;
2018
2019 case 'U' :
2e076ddf 2020 /* ??? wip */
8c5ca3b9
DE
2021 /* Output a load/store with update indicator if appropriate. */
2022 if (GET_CODE (x) == MEM)
2023 {
2024 if (GET_CODE (XEXP (x, 0)) == PRE_INC
2025 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
2026 fputs (".a", file);
2027 }
2028 else
2029 output_operand_lossage ("invalid operand to %U code");
2030 return;
2031
2032 case 'N' :
2033 /* Print a constant value negated. */
2034 if (GET_CODE (x) == CONST_INT)
2035 output_addr_const (file, GEN_INT (- INTVAL (x)));
2036 else
2037 output_operand_lossage ("invalid operand to %N code");
2038 return;
2039
4d6c607f
DE
2040 case 'X' :
2041 /* Print a const_int in hex. Used in comments. */
2042 if (GET_CODE (x) == CONST_INT)
2043 fprintf (file,
2044#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2045 "0x%x",
2046#else
2047 "0x%lx",
2048#endif
2049 INTVAL (x));
2050 return;
2051
8c5ca3b9
DE
2052 case '#' :
2053 fputs (IMMEDIATE_PREFIX, file);
2054 return;
2055
2056#if 0 /* ??? no longer used */
2057 case '@' :
2058 fputs (reg_names[SDA_REGNUM], file);
2059 return;
2060#endif
2061
2062 case 0 :
2063 /* Do nothing special. */
2064 break;
2065
2066 default :
2067 /* Unknown flag. */
2068 output_operand_lossage ("invalid operand output code");
2069 }
2070
2071 switch (GET_CODE (x))
2072 {
2073 case REG :
2074 fputs (reg_names[REGNO (x)], file);
2075 break;
2076
2077 case MEM :
5b8ae21f
MM
2078 addr = XEXP (x, 0);
2079 if (GET_CODE (addr) == PRE_INC)
2080 {
2081 if (GET_CODE (XEXP (addr, 0)) != REG)
2082 abort ();
2083
2084 fprintf (file, "@+%s", reg_names[REGNO (XEXP (addr, 0))]);
2085 }
2086 else if (GET_CODE (addr) == PRE_DEC)
2087 {
2088 if (GET_CODE (XEXP (addr, 0)) != REG)
2089 abort ();
2090
2091 fprintf (file, "@-%s", reg_names[REGNO (XEXP (addr, 0))]);
2092 }
2093 else if (GET_CODE (addr) == POST_INC)
2094 {
2095 if (GET_CODE (XEXP (addr, 0)) != REG)
2096 abort ();
2097
2098 fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
2099 }
8c5ca3b9 2100 else
5b8ae21f
MM
2101 {
2102 fputs ("@(", file);
2103 output_address (XEXP (x, 0));
2104 fputc (')', file);
2105 }
8c5ca3b9
DE
2106 break;
2107
2108 case CONST_DOUBLE :
2109 /* We handle SFmode constants here as output_addr_const doesn't. */
2110 if (GET_MODE (x) == SFmode)
2111 {
2112 REAL_VALUE_TYPE d;
2113 long l;
2114
2115 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
2116 REAL_VALUE_TO_TARGET_SINGLE (d, l);
2117 fprintf (file, "0x%08lx", l);
2118 break;
2119 }
2120
2121 /* Fall through. Let output_addr_const deal with it. */
2122
2123 default :
2124 output_addr_const (file, x);
2125 break;
2126 }
2127}
2128
2129/* Print a memory address as an operand to reference that memory location. */
2130
2131void
2132m32r_print_operand_address (file, addr)
2e076ddf
NC
2133 FILE * file;
2134 rtx addr;
8c5ca3b9 2135{
2e076ddf
NC
2136 register rtx base;
2137 register rtx index = 0;
2138 int offset = 0;
8c5ca3b9
DE
2139
2140 switch (GET_CODE (addr))
2141 {
2142 case REG :
2143 fputs (reg_names[REGNO (addr)], file);
2144 break;
2145
2146 case PLUS :
2147 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
2148 offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
2149 else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
2150 offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
2151 else
2152 base = XEXP (addr, 0), index = XEXP (addr, 1);
2153 if (GET_CODE (base) == REG)
2154 {
2155 /* Print the offset first (if present) to conform to the manual. */
2156 if (index == 0)
2157 {
2158 if (offset != 0)
2159 fprintf (file, "%d,", offset);
2160 fputs (reg_names[REGNO (base)], file);
2161 }
2162 /* The chip doesn't support this, but left in for generality. */
2163 else if (GET_CODE (index) == REG)
2164 fprintf (file, "%s,%s",
2165 reg_names[REGNO (base)], reg_names[REGNO (index)]);
2166 /* Not sure this can happen, but leave in for now. */
2167 else if (GET_CODE (index) == SYMBOL_REF)
2168 {
2169 output_addr_const (file, index);
2170 fputc (',', file);
2171 fputs (reg_names[REGNO (base)], file);
2172 }
2173 else
2174 abort ();
2175 }
2176 else if (GET_CODE (base) == LO_SUM)
2177 {
2178 if (index != 0
2179 || GET_CODE (XEXP (base, 0)) != REG)
2180 abort ();
2181 if (small_data_operand (XEXP (base, 1), VOIDmode))
2182 fputs ("sda(", file);
2183 else
2184 fputs ("low(", file);
2185 output_addr_const (file, plus_constant (XEXP (base, 1), offset));
2186 fputs ("),", file);
2187 fputs (reg_names[REGNO (XEXP (base, 0))], file);
2188 }
2189 else
2190 abort ();
2191 break;
2192
2193 case LO_SUM :
2194 if (GET_CODE (XEXP (addr, 0)) != REG)
2195 abort ();
2196 if (small_data_operand (XEXP (addr, 1), VOIDmode))
2197 fputs ("sda(", file);
2198 else
2199 fputs ("low(", file);
2200 output_addr_const (file, XEXP (addr, 1));
2201 fputs ("),", file);
2202 fputs (reg_names[REGNO (XEXP (addr, 0))], file);
2203 break;
2204
5b8ae21f
MM
2205 case PRE_INC : /* Assume SImode */
2206 fprintf (file, "+%s", reg_names[REGNO (XEXP (addr, 0))]);
2207 break;
2208
2209 case PRE_DEC : /* Assume SImode */
2210 fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]);
2211 break;
2212
2213 case POST_INC : /* Assume SImode */
2214 fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]);
8c5ca3b9
DE
2215 break;
2216
2217 default :
2218 output_addr_const (file, addr);
2219 break;
2220 }
2221}
2b7972b0
MM
2222
2223/* Return true if the operands are the constants 0 and 1. */
2224int
2225zero_and_one (operand1, operand2)
2226 rtx operand1;
2227 rtx operand2;
2228{
2229 return
2230 GET_CODE (operand1) == CONST_INT
2231 && GET_CODE (operand2) == CONST_INT
2232 && ( ((INTVAL (operand1) == 0) && (INTVAL (operand2) == 1))
2233 ||((INTVAL (operand1) == 1) && (INTVAL (operand2) == 0)));
2234}
2235
2236/* Return non-zero if the operand is suitable for use in a conditional move sequence. */
2237int
2238conditional_move_operand (operand, int_mode)
2239 rtx operand;
2240 int int_mode;
2241{
2242 enum machine_mode mode = (enum machine_mode)int_mode;
2243
2244 /* Only defined for simple integers so far... */
2245 if (mode != SImode && mode != HImode && mode != QImode)
2246 return FALSE;
2247
2248 /* At the moment we can hanndle moving registers and loading constants. */
2249 /* To be added: Addition/subtraction/bitops/multiplication of registers. */
2250
2251 switch (GET_CODE (operand))
2252 {
2253 case REG:
2254 return 1;
2255
2256 case CONST_INT:
2257 return INT8_P (INTVAL (operand));
2258
2259 default:
2260#if 0
2261 fprintf (stderr, "Test for cond move op of type: %s\n",
2262 GET_RTX_NAME (GET_CODE (operand)));
2263#endif
2264 return 0;
2265 }
2266}
2267
2268/* Return true if the code is a test of the carry bit */
2269int
2270carry_compare_operand (op, int_mode)
2271 rtx op;
2272 int int_mode;
2273{
2274 rtx x;
2275
51c10c4e 2276 if (GET_MODE (op) != SImode && GET_MODE (op) != VOIDmode)
2b7972b0
MM
2277 return FALSE;
2278
2279 if (GET_CODE (op) != NE && GET_CODE (op) != EQ)
2280 return FALSE;
2281
2282 x = XEXP (op, 0);
2283 if (GET_CODE (x) != REG || REGNO (x) != CARRY_REGNUM)
2284 return FALSE;
2285
2286 x = XEXP (op, 1);
2287 if (GET_CODE (x) != CONST_INT || INTVAL (x) != 0)
2288 return FALSE;
2289
2290 return TRUE;
2291}
2292
2293
2294/* Generate the correct assembler code to handle the conditional loading of a
2295 value into a register. It is known that the operands satisfy the
2296 conditional_move_operand() function above. The destination is operand[0].
2297 The condition is operand [1]. The 'true' value is operand [2] and the
2298 'false' value is operand [3]. */
2299char *
2300emit_cond_move (operands, insn)
2301 rtx * operands;
2302 rtx insn;
2303{
2304 static char buffer [100];
51c10c4e
NC
2305 char * dest = reg_names [REGNO (operands [0])];
2306
2b7972b0
MM
2307 buffer [0] = 0;
2308
2309 /* Destination must be a register. */
2310 if (GET_CODE (operands [0]) != REG)
2311 abort();
2312 if (! conditional_move_operand (operands [2], SImode))
2313 abort();
2314 if (! conditional_move_operand (operands [3], SImode))
2315 abort();
2316
2b7972b0
MM
2317 /* Check to see if the test is reversed. */
2318 if (GET_CODE (operands [1]) == NE)
2319 {
2320 rtx tmp = operands [2];
2321 operands [2] = operands [3];
2322 operands [3] = tmp;
2323 }
2324
51c10c4e
NC
2325 sprintf (buffer, "mvfc %s, cbr", dest);
2326
2327 /* If the true value was '0' then we need to invert the results of the move. */
2328 if (INTVAL (operands [2]) == 0)
2329 sprintf (buffer + strlen (buffer), "\n\txor3 %s, %s, #1",
2330 dest, dest);
2331
2b7972b0
MM
2332 return buffer;
2333}
2334
d2a73f8e
NC
2335
2336\f
2337/* Use a library function to move some bytes. */
2338static void
2339block_move_call (dest_reg, src_reg, bytes_rtx)
2340 rtx dest_reg;
2341 rtx src_reg;
2342 rtx bytes_rtx;
2343{
2344 /* We want to pass the size as Pmode, which will normally be SImode
2345 but will be DImode if we are using 64 bit longs and pointers. */
2346 if (GET_MODE (bytes_rtx) != VOIDmode
2347 && GET_MODE (bytes_rtx) != Pmode)
2348 bytes_rtx = convert_to_mode (Pmode, bytes_rtx, 1);
2349
2350#ifdef TARGET_MEM_FUNCTIONS
2351 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
2352 VOIDmode, 3, dest_reg, Pmode, src_reg, Pmode,
2353 convert_to_mode (TYPE_MODE (sizetype), bytes_rtx,
2354 TREE_UNSIGNED (sizetype)),
2355 TYPE_MODE (sizetype));
2356#else
2357 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0,
2358 VOIDmode, 3, src_reg, Pmode, dest_reg, Pmode,
2359 convert_to_mode (TYPE_MODE (integer_type_node), bytes_rtx,
2360 TREE_UNSIGNED (integer_type_node)),
2361 TYPE_MODE (integer_type_node));
2362#endif
2363}
2364
2365/* The maximum number of bytes to copy using pairs of load/store instructions.
2366 If a block is larger than this then a loop will be generated to copy
2367 MAX_MOVE_BYTES chunks at a time. The value of 32 is a semi-arbitary choice.
2368 A customer uses Dhrystome as their benchmark, and Dhrystone has a 31 byte
2369 string copy in it. */
2370#define MAX_MOVE_BYTES 32
2371
2372/* Expand string/block move operations.
2373
2374 operands[0] is the pointer to the destination.
2375 operands[1] is the pointer to the source.
2376 operands[2] is the number of bytes to move.
2377 operands[3] is the alignment. */
2378
2379void
2380m32r_expand_block_move (operands)
2381 rtx operands[];
2382{
2383 rtx orig_dst = operands[0];
2384 rtx orig_src = operands[1];
2385 rtx bytes_rtx = operands[2];
2386 rtx align_rtx = operands[3];
2387 int constp = GET_CODE (bytes_rtx) == CONST_INT;
2388 HOST_WIDE_INT bytes = constp ? INTVAL (bytes_rtx) : 0;
2389 int align = INTVAL (align_rtx);
2390 int leftover;
2391 rtx src_reg;
2392 rtx dst_reg;
2393
2394 if (constp && bytes <= 0)
2395 return;
2396
2397 /* Move the address into scratch registers. */
2398 dst_reg = copy_addr_to_reg (XEXP (orig_dst, 0));
2399 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
2400
2401 if (align > UNITS_PER_WORD)
2402 align = UNITS_PER_WORD;
2403
2404 /* If we prefer size over speed, always use a function call.
2405 If we do not know the size, use a function call.
2406 If the blocks are not word aligned, use a function call. */
2407 if (optimize_size || ! constp || align != UNITS_PER_WORD)
2408 {
2409 block_move_call (dst_reg, src_reg, bytes_rtx);
2410 return;
2411 }
2412
2413 leftover = bytes % MAX_MOVE_BYTES;
2414 bytes -= leftover;
2415
2416 /* If necessary, generate a loop to handle the bulk of the copy. */
2417 if (bytes)
2418 {
2419 rtx label;
2420 rtx final_src;
0ae9f65b
DE
2421 rtx at_a_time = GEN_INT (MAX_MOVE_BYTES);
2422 rtx rounded_total = GEN_INT (bytes);
d2a73f8e
NC
2423
2424 /* If we are going to have to perform this loop more than
2425 once, then generate a label and compute the address the
2426 source register will contain upon completion of the final
2427 itteration. */
2428 if (bytes > MAX_MOVE_BYTES)
2429 {
2430 final_src = gen_reg_rtx (Pmode);
2431
2432 if (INT16_P(bytes))
0ae9f65b 2433 emit_insn (gen_addsi3 (final_src, src_reg, rounded_total));
d2a73f8e
NC
2434 else
2435 {
0ae9f65b 2436 emit_insn (gen_movsi (final_src, rounded_total));
d2a73f8e
NC
2437 emit_insn (gen_addsi3 (final_src, final_src, src_reg));
2438 }
2439
2440 label = gen_label_rtx ();
2441 emit_label (label);
2442 }
2443
2444 /* It is known that output_block_move() will update src_reg to point
2445 to the word after the end of the source block, and dst_reg to point
2446 to the last word of the destination block, provided that the block
2447 is MAX_MOVE_BYTES long. */
0ae9f65b 2448 emit_insn (gen_movstrsi_internal (dst_reg, src_reg, at_a_time));
d2a73f8e
NC
2449 emit_insn (gen_addsi3 (dst_reg, dst_reg, GEN_INT (4)));
2450
2451 if (bytes > MAX_MOVE_BYTES)
2452 {
2453 emit_insn (gen_cmpsi (src_reg, final_src));
2454 emit_jump_insn (gen_bne (label));
2455 }
2456 }
2457
2458 if (leftover)
2459 emit_insn (gen_movstrsi_internal (dst_reg, src_reg, GEN_INT (leftover)));
2460}
2461
2462\f
2463/* Emit load/stores for a small constant word aligned block_move.
2464
2465 operands[0] is the memory address of the destination.
2466 operands[1] is the memory address of the source.
2467 operands[2] is the number of bytes to move.
2468 operands[3] is a temp register.
2469 operands[4] is a temp register. */
2470
2471char *
2472m32r_output_block_move (insn, operands)
2473 rtx insn;
2474 rtx operands[];
2475{
2476 HOST_WIDE_INT bytes = INTVAL (operands[2]);
2477 int first_time;
2478 int got_extra = 0;
2479
2480 if (bytes < 1 || bytes > MAX_MOVE_BYTES)
2481 abort ();
2482
2483 /* We do not have a post-increment store available, so the first set of
2484 stores are done without any increment, then the remaining ones can use
2485 the pre-increment addressing mode.
2486
2487 Note: expand_block_move() also relies upon this behaviour when building
2488 loops to copy large blocks. */
2489 first_time = 1;
2490
2491 while (bytes > 0)
2492 {
2493 if (bytes >= 8)
2494 {
2495 if (first_time)
2496 {
2497 output_asm_insn ("ld\t%3, %p1", operands);
2498 output_asm_insn ("ld\t%4, %p1", operands);
2499 output_asm_insn ("st\t%3, @%0", operands);
2500 output_asm_insn ("st\t%4, %s0", operands);
2501 }
2502 else
2503 {
2504 output_asm_insn ("ld\t%3, %p1", operands);
2505 output_asm_insn ("ld\t%4, %p1", operands);
2506 output_asm_insn ("st\t%3, %s0", operands);
2507 output_asm_insn ("st\t%4, %s0", operands);
2508 }
2509
2510 bytes -= 8;
2511 }
2512 else if (bytes >= 4)
2513 {
2514 if (bytes > 4)
2515 got_extra = 1;
2516
2517 output_asm_insn ("ld\t%3, %p1", operands);
2518
2519 if (got_extra)
2520 output_asm_insn ("ld\t%4, %p1", operands);
2521
2522 if (first_time)
2523 output_asm_insn ("st\t%3, @%0", operands);
2524 else
2525 output_asm_insn ("st\t%3, %s0", operands);
2526
2527 bytes -= 4;
2528 }
2529 else
2530 {
2531 /* Get the entire next word, even though we do not want all of it.
2532 The saves us from doing several smaller loads, and we assume that
2533 we cannot cause a page fault when at least part of the word is in
0ae9f65b
DE
2534 valid memory [since we don't get called if things aren't properly
2535 aligned]. */
2536 int dst_offset = first_time ? 0 : 4;
2537 int last_shift;
2538 rtx my_operands[3];
2539
2540 /* If got_extra is true then we have already loaded
d2a73f8e
NC
2541 the next word as part of loading and storing the previous word. */
2542 if (! got_extra)
2543 output_asm_insn ("ld\t%4, @%1", operands);
2544
2545 if (bytes >= 2)
2546 {
2547 bytes -= 2;
2548
0ae9f65b
DE
2549 output_asm_insn ("sra3\t%3, %4, #16", operands);
2550 my_operands[0] = operands[3];
2551 my_operands[1] = GEN_INT (dst_offset);
2552 my_operands[2] = operands[0];
2553 output_asm_insn ("sth\t%0, @(%1,%2)", my_operands);
d2a73f8e
NC
2554
2555 /* If there is a byte left to store then increment the
2556 destination address and shift the contents of the source
0ae9f65b 2557 register down by 8 bits. We could not do the address
d2a73f8e
NC
2558 increment in the store half word instruction, because it does
2559 not have an auto increment mode. */
2560 if (bytes > 0) /* assert (bytes == 1) */
2561 {
0ae9f65b
DE
2562 dst_offset += 2;
2563 last_shift = 8;
d2a73f8e
NC
2564 }
2565 }
0ae9f65b
DE
2566 else
2567 last_shift = 24;
2568
2569 if (bytes > 0)
2570 {
2571 my_operands[0] = operands[4];
2572 my_operands[1] = GEN_INT (last_shift);
2573 output_asm_insn ("srai\t%0, #%1", my_operands);
2574 my_operands[0] = operands[4];
2575 my_operands[1] = GEN_INT (dst_offset);
2576 my_operands[2] = operands[0];
2577 output_asm_insn ("stb\t%0, @(%1,%2)", my_operands);
2578 }
d2a73f8e
NC
2579
2580 bytes = 0;
2581 }
2582
2583 first_time = 0;
2584 }
2585
2586 return "";
2587}
2588
2589/* Return true if op is an integer constant, less than or equal to
2590 MAX_MOVE_BYTES. */
2591int
2592m32r_block_immediate_operand (op, mode)
2593 rtx op;
2594 int mode;
2595{
2596 if (GET_CODE (op) != CONST_INT
2597 || INTVAL (op) > MAX_MOVE_BYTES
2598 || INTVAL (op) <= 0)
2599 return 0;
2600
2601 return 1;
2602}