]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/mn10300/mn10300.c
Patches to fix minor optimizer bugs
[thirdparty/gcc.git] / gcc / config / mn10300 / mn10300.c
CommitLineData
11bb1f11 1/* Subroutines for insn-output.c for Matsushita MN10300 series
74452ac3 2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
11bb1f11
JL
3 Contributed by Jeff Law (law@cygnus.com).
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22#include <stdio.h>
23#include "config.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 "recog.h"
35#include "expr.h"
36#include "tree.h"
37#include "obstack.h"
38
74452ac3
JL
39/* Global registers known to hold the value zero.
40
41 Normally we'd depend on CSE and combine to put zero into a
42 register and re-use it.
43
44 However, on the mn10x00 processors we implicitly use the constant
45 zero in tst instructions, so we might be able to do better by
46 loading the value into a register in the prologue, then re-useing
47 that register throughout the function.
48
49 We could perform similar optimizations for other constants, but with
50 gcse due soon, it doesn't seem worth the effort.
51
52 These variables hold a rtx for a register known to hold the value
53 zero throughout the entire function, or NULL if no register of
54 the appropriate class has such a value throughout the life of the
55 function. */
56rtx zero_dreg;
57rtx zero_areg;
58
11bb1f11
JL
59void
60asm_file_start (file)
61 FILE *file;
62{
63 fprintf (file, "#\tGCC For the Matsushita MN10300\n");
64 if (optimize)
65 fprintf (file, "# -O%d\n", optimize);
66 else
67 fprintf (file, "\n\n");
68 output_file_directive (file, main_input_filename);
69}
70\f
71
11bb1f11
JL
72/* Print operand X using operand code CODE to assembly language output file
73 FILE. */
74
75void
76print_operand (file, x, code)
77 FILE *file;
78 rtx x;
79 int code;
80{
81 switch (code)
82 {
83 case 'b':
84 case 'B':
85 /* These are normal and reversed branches. */
86 switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
87 {
88 case NE:
89 fprintf (file, "ne");
90 break;
91 case EQ:
92 fprintf (file, "eq");
93 break;
94 case GE:
95 fprintf (file, "ge");
96 break;
97 case GT:
98 fprintf (file, "gt");
99 break;
100 case LE:
101 fprintf (file, "le");
102 break;
103 case LT:
104 fprintf (file, "lt");
105 break;
106 case GEU:
107 fprintf (file, "cc");
108 break;
109 case GTU:
110 fprintf (file, "hi");
111 break;
112 case LEU:
113 fprintf (file, "ls");
114 break;
115 case LTU:
116 fprintf (file, "cs");
117 break;
118 default:
119 abort ();
120 }
121 break;
122 case 'C':
123 /* This is used for the operand to a call instruction;
124 if it's a REG, enclose it in parens, else output
125 the operand normally. */
126 if (GET_CODE (x) == REG)
127 {
128 fputc ('(', file);
129 print_operand (file, x, 0);
130 fputc (')', file);
131 }
132 else
133 print_operand (file, x, 0);
134 break;
135
38c37a0e
JL
136 /* These are the least significant word in a 64bit value. */
137 case 'L':
138 switch (GET_CODE (x))
139 {
140 case MEM:
141 fputc ('(', file);
142 output_address (XEXP (x, 0));
143 fputc (')', file);
144 break;
145
146 case REG:
147 fprintf (file, "%s", reg_names[REGNO (x)]);
148 break;
149
150 case SUBREG:
151 fprintf (file, "%s",
152 reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
153 break;
154
155 case CONST_DOUBLE:
156 {
157 long val[2];
158 REAL_VALUE_TYPE rv;
159
160 switch (GET_MODE (x))
161 {
162 case DFmode:
163 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
164 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
165 print_operand_address (file, GEN_INT (val[0]));
166 break;;
167 case SFmode:
168 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
169 REAL_VALUE_TO_TARGET_SINGLE (rv, val[0]);
170 print_operand_address (file, GEN_INT (val[0]));
171 break;;
172 case VOIDmode:
173 case DImode:
174 print_operand_address (file,
175 GEN_INT (CONST_DOUBLE_LOW (x)));
176 break;
177 }
178 break;
179 }
180
181 case CONST_INT:
182 print_operand_address (file, x);
183 break;
184
185 default:
186 abort ();
187 }
188 break;
189
190 /* Similarly, but for the most significant word. */
191 case 'H':
192 switch (GET_CODE (x))
193 {
194 case MEM:
195 fputc ('(', file);
196 x = adj_offsettable_operand (x, 4);
197 output_address (XEXP (x, 0));
198 fputc (')', file);
199 break;
200
201 case REG:
202 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
203 break;
204
205 case SUBREG:
206 fprintf (file, "%s",
207 reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)] + 1);
208 break;
209
210 case CONST_DOUBLE:
211 {
212 long val[2];
213 REAL_VALUE_TYPE rv;
214
215 switch (GET_MODE (x))
216 {
217 case DFmode:
218 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
219 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
220 print_operand_address (file, GEN_INT (val[1]));
221 break;;
222 case SFmode:
223 abort ();
224 case VOIDmode:
225 case DImode:
226 print_operand_address (file,
227 GEN_INT (CONST_DOUBLE_HIGH (x)));
228 break;
229 }
230 break;
231 }
232
233 case CONST_INT:
234 if (INTVAL (x) < 0)
235 print_operand_address (file, GEN_INT (-1));
236 else
237 print_operand_address (file, GEN_INT (0));
238 break;
239 default:
240 abort ();
241 }
242 break;
243
244 case 'A':
245 fputc ('(', file);
246 if (GET_CODE (XEXP (x, 0)) == REG)
247 output_address (gen_rtx (PLUS, SImode, XEXP (x, 0), GEN_INT (0)));
248 else
249 output_address (XEXP (x, 0));
250 fputc (')', file);
251 break;
252
6fafc523
JL
253 case 'N':
254 output_address (GEN_INT ((~INTVAL (x)) & 0xff));
255 break;
256
11bb1f11
JL
257 default:
258 switch (GET_CODE (x))
259 {
260 case MEM:
261 fputc ('(', file);
262 output_address (XEXP (x, 0));
263 fputc (')', file);
264 break;
265
38c37a0e
JL
266 case PLUS:
267 output_address (x);
268 break;
269
11bb1f11
JL
270 case REG:
271 fprintf (file, "%s", reg_names[REGNO (x)]);
272 break;
273
274 case SUBREG:
275 fprintf (file, "%s",
276 reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
277 break;
278
38c37a0e
JL
279 /* This will only be single precision.... */
280 case CONST_DOUBLE:
281 {
282 unsigned long val;
283 REAL_VALUE_TYPE rv;
284
285 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
286 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
287 print_operand_address (file, GEN_INT (val));
288 break;
289 }
290
11bb1f11
JL
291 case CONST_INT:
292 case SYMBOL_REF:
293 case CONST:
294 case LABEL_REF:
295 case CODE_LABEL:
296 print_operand_address (file, x);
297 break;
298 default:
299 abort ();
300 }
301 break;
302 }
303}
304
305/* Output assembly language output for the address ADDR to FILE. */
306
307void
308print_operand_address (file, addr)
309 FILE *file;
310 rtx addr;
311{
312 switch (GET_CODE (addr))
313 {
314 case REG:
315 if (addr == stack_pointer_rtx)
316 print_operand_address (file, gen_rtx (PLUS, SImode,
317 stack_pointer_rtx,
318 GEN_INT (0)));
319 else
320 print_operand (file, addr, 0);
321 break;
322 case PLUS:
323 {
324 rtx base, index;
325 if (REG_P (XEXP (addr, 0))
326 && REG_OK_FOR_BASE_P (XEXP (addr, 0)))
327 base = XEXP (addr, 0), index = XEXP (addr, 1);
328 else if (REG_P (XEXP (addr, 1))
329 && REG_OK_FOR_BASE_P (XEXP (addr, 1)))
330 base = XEXP (addr, 1), index = XEXP (addr, 0);
331 else
332 abort ();
333 print_operand (file, index, 0);
334 fputc (',', file);
335 print_operand (file, base, 0);;
336 break;
337 }
338 case SYMBOL_REF:
339 output_addr_const (file, addr);
340 break;
341 default:
342 output_addr_const (file, addr);
343 break;
344 }
345}
346
38c37a0e
JL
347int
348can_use_return_insn ()
349{
460f4b9d
JL
350 /* size includes the fixed stack space needed for function calls. */
351 int size = get_frame_size () + current_function_outgoing_args_size;
352
353 /* And space for the return pointer. */
354 size += current_function_outgoing_args_size ? 4 : 0;
38c37a0e
JL
355
356 return (reload_completed
357 && size == 0
358 && !regs_ever_live[2]
359 && !regs_ever_live[3]
360 && !regs_ever_live[6]
361 && !regs_ever_live[7]
362 && !frame_pointer_needed);
363}
364
74452ac3
JL
365/* Count the number of tst insns which compare a data or address
366 register with zero. */
367static void
368count_tst_insns (dreg_countp, areg_countp)
369 int *dreg_countp;
370 int *areg_countp;
371{
372 rtx insn;
373
374 /* Assume no tst insns exist. */
375 *dreg_countp = 0;
376 *areg_countp = 0;
377
378 /* If not optimizing, then quit now. */
379 if (!optimize)
380 return;
381
382 /* Walk through all the insns. */
383 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
384 {
385 rtx pat;
386
387 /* Ignore anything that is not a normal INSN. */
388 if (GET_CODE (insn) != INSN)
389 continue;
390
391 /* Ignore anything that isn't a SET. */
392 pat = PATTERN (insn);
393 if (GET_CODE (pat) != SET)
394 continue;
395
396 /* Check for a tst insn. */
397 if (SET_DEST (pat) == cc0_rtx
398 && GET_CODE (SET_SRC (pat)) == REG)
399 {
400 if (REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == DATA_REGS)
401 (*dreg_countp)++;
402
403 if (REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == ADDRESS_REGS)
404 (*areg_countp)++;
405 }
406
407 /* Setting an address register to zero can also be optimized,
408 so count it just like a tst insn. */
409 if (GET_CODE (SET_DEST (pat)) == REG
410 && GET_CODE (SET_SRC (pat)) == CONST_INT
411 && INTVAL (SET_SRC (pat)) == 0
412 && REGNO_REG_CLASS (REGNO (SET_DEST (pat))) == ADDRESS_REGS)
413 (*areg_countp)++;
414 }
415}
416
11bb1f11
JL
417void
418expand_prologue ()
419{
3dbc43d1
JL
420 unsigned int size;
421
6c0870b8
JL
422 /* We need to end the current sequence so that count_tst_insns can
423 look at all the insns in this function. Normally this would be
424 unsafe, but it's OK in the prologue/epilogue expanders. */
425 end_sequence ();
426
74452ac3
JL
427 /* Determine if it is profitable to put the value zero into a register
428 for the entire function. If so, set ZERO_DREG and ZERO_AREG. */
429 if (regs_ever_live[2] || regs_ever_live[3]
430 || regs_ever_live[6] || regs_ever_live[7]
431 || frame_pointer_needed)
432 {
433 int dreg_count, areg_count;
434
435 /* Get a count of the number of tst insns which use address and
436 data registers. */
437 count_tst_insns (&dreg_count, &areg_count);
438
439 /* If there's more than one tst insn using a data register, then
440 this optimization is a win. */
441 if (dreg_count > 1
442 && (!regs_ever_live[2] || !regs_ever_live[3]))
443 {
444 if (!regs_ever_live[2])
445 {
446 regs_ever_live[2] = 1;
447 zero_dreg = gen_rtx (REG, SImode, 2);
448 }
449 else
450 {
451 regs_ever_live[3] = 1;
452 zero_dreg = gen_rtx (REG, SImode, 3);
453 }
454 }
455 else
456 zero_dreg = NULL_RTX;
457
458 /* If there's more than two tst insns using an address register,
459 then this optimization is a win. */
460 if (areg_count > 2
461 && (!regs_ever_live[6] || !regs_ever_live[7]))
462 {
463 if (!regs_ever_live[6])
464 {
465 regs_ever_live[6] = 1;
466 zero_areg = gen_rtx (REG, SImode, 6);
467 }
468 else
469 {
470 regs_ever_live[7] = 1;
471 zero_areg = gen_rtx (REG, SImode, 7);
472 }
473 }
474 else
475 zero_areg = NULL_RTX;
476 }
477 else
478 {
479 zero_dreg = NULL_RTX;
480 zero_areg = NULL_RTX;
481 }
482
6c0870b8
JL
483 /* Start a new sequence. */
484 start_sequence ();
485
3dbc43d1 486 /* SIZE includes the fixed stack space needed for function calls. */
460f4b9d
JL
487 size = get_frame_size () + current_function_outgoing_args_size;
488 size += (current_function_outgoing_args_size ? 4 : 0);
11bb1f11 489
22ef4e9b
JL
490 /* If this is an old-style varargs function, then its arguments
491 need to be flushed back to the stack. */
492 if (current_function_varargs)
493 {
494 emit_move_insn (gen_rtx (MEM, SImode,
495 gen_rtx (PLUS, Pmode, stack_pointer_rtx,
496 GEN_INT (4))),
497 gen_rtx (REG, SImode, 0));
498 emit_move_insn (gen_rtx (MEM, SImode,
499 gen_rtx (PLUS, Pmode, stack_pointer_rtx,
500 GEN_INT (8))),
501 gen_rtx (REG, SImode, 1));
502 }
503
777fbf09
JL
504 /* And now store all the registers onto the stack with a
505 single two byte instruction. */
506 if (regs_ever_live[2] || regs_ever_live[3]
507 || regs_ever_live[6] || regs_ever_live[7]
508 || frame_pointer_needed)
509 emit_insn (gen_store_movm ());
510
511 /* Now put the frame pointer into the frame pointer register. */
11bb1f11 512 if (frame_pointer_needed)
6e86170d 513 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
11bb1f11 514
777fbf09 515 /* Allocate stack for this frame. */
11bb1f11
JL
516 if (size)
517 emit_insn (gen_addsi3 (stack_pointer_rtx,
518 stack_pointer_rtx,
519 GEN_INT (-size)));
74452ac3
JL
520
521 /* Load zeros into registers as needed. */
522 if (zero_dreg)
523 emit_move_insn (zero_dreg, const0_rtx);
524
525 if (zero_areg)
526 emit_move_insn (zero_areg, const0_rtx);
11bb1f11
JL
527}
528
529void
530expand_epilogue ()
531{
3dbc43d1
JL
532 unsigned int size;
533
3dbc43d1 534 /* SIZE includes the fixed stack space needed for function calls. */
460f4b9d
JL
535 size = get_frame_size () + current_function_outgoing_args_size;
536 size += (current_function_outgoing_args_size ? 4 : 0);
11bb1f11
JL
537
538 /* Cut back the stack. */
539 if (frame_pointer_needed)
540 {
11bb1f11 541 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
4246e0c5
JL
542 size = 0;
543 }
6fafc523
JL
544 else if ((regs_ever_live[2] || regs_ever_live[3]
545 || regs_ever_live[6] || regs_ever_live[7])
546 && size > 255)
4246e0c5
JL
547 {
548 emit_insn (gen_addsi3 (stack_pointer_rtx,
549 stack_pointer_rtx,
550 GEN_INT (size)));
551 size = 0;
11bb1f11 552 }
11bb1f11 553
777fbf09
JL
554 /* For simplicity, we just movm all the callee saved registers to
555 the stack with one instruction.
556
557 ?!? Only save registers which are actually used. Reduces
558 stack requireents and is faster. */
559 if (regs_ever_live[2] || regs_ever_live[3]
560 || regs_ever_live[6] || regs_ever_live[7]
561 || frame_pointer_needed)
562 emit_jump_insn (gen_return_internal_regs (GEN_INT (size)));
563 else
564 {
565 if (size)
38c37a0e
JL
566 {
567 emit_insn (gen_addsi3 (stack_pointer_rtx,
568 stack_pointer_rtx,
569 GEN_INT (size)));
570 emit_jump_insn (gen_return_internal ());
571 }
572 else
573 {
574 emit_jump_insn (gen_return ());
575 }
777fbf09 576 }
11bb1f11
JL
577}
578
579/* Update the condition code from the insn. */
580
581void
582notice_update_cc (body, insn)
583 rtx body;
584 rtx insn;
585{
11bb1f11
JL
586 switch (get_attr_cc (insn))
587 {
588 case CC_NONE:
589 /* Insn does not affect CC at all. */
590 break;
591
592 case CC_NONE_0HIT:
593 /* Insn does not change CC, but the 0'th operand has been changed. */
594 if (cc_status.value1 != 0
595 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
596 cc_status.value1 = 0;
597 break;
598
d116300b 599 case CC_SET_ZN:
11bb1f11 600 /* Insn sets the Z,N flags of CC to recog_operand[0].
d116300b 601 V,C are unusable. */
11bb1f11 602 CC_STATUS_INIT;
d116300b 603 cc_status.flags |= CC_NO_CARRY | CC_OVERFLOW_UNUSABLE;
11bb1f11
JL
604 cc_status.value1 = recog_operand[0];
605 break;
606
d116300b
JL
607 case CC_SET_ZNV:
608 /* Insn sets the Z,N,V flags of CC to recog_operand[0].
609 C is unusable. */
82c6faa8 610 CC_STATUS_INIT;
d116300b 611 cc_status.flags |= CC_NO_CARRY;
82c6faa8
JL
612 cc_status.value1 = recog_operand[0];
613 break;
614
11bb1f11
JL
615 case CC_COMPARE:
616 /* The insn is a compare instruction. */
617 CC_STATUS_INIT;
618 cc_status.value1 = SET_SRC (body);
619 break;
620
3b800f71
JL
621 case CC_INVERT:
622 /* The insn is a compare instruction. */
623 CC_STATUS_INIT;
624 cc_status.value1 = SET_SRC (body);
625 cc_status.flags |= CC_INVERTED;
626 break;
627
11bb1f11
JL
628 case CC_CLOBBER:
629 /* Insn doesn't leave CC in a usable state. */
630 CC_STATUS_INIT;
631 break;
82c6faa8
JL
632
633 default:
634 abort ();
11bb1f11 635 }
11bb1f11
JL
636}
637
638/* Return true if OP is a valid call operand. */
639
640int
641call_address_operand (op, mode)
642 rtx op;
643 enum machine_mode mode;
644{
645 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
646}
647
648/* What (if any) secondary registers are needed to move IN with mode
649 MODE into a register from in register class CLASS.
650
651 We might be able to simplify this. */
652enum reg_class
653secondary_reload_class (class, mode, in)
654 enum reg_class class;
655 enum machine_mode mode;
656 rtx in;
657{
658 int regno;
659
660 /* Memory loads less than a full word wide can't have an
661 address or stack pointer destination. They must use
662 a data register as an intermediate register. */
663 if (GET_CODE (in) == MEM
664 && (mode == QImode || mode == HImode)
665 && (class == ADDRESS_REGS || class == SP_REGS))
666 return DATA_REGS;
667
668 /* We can't directly load sp + const_int into a data register;
669 we must use an address register as an intermediate. */
777fbf09
JL
670 if (class != SP_REGS
671 && class != ADDRESS_REGS
672 && class != SP_OR_ADDRESS_REGS
11bb1f11
JL
673 && (in == stack_pointer_rtx
674 || (GET_CODE (in) == PLUS
777fbf09
JL
675 && (XEXP (in, 0) == stack_pointer_rtx
676 || XEXP (in, 1) == stack_pointer_rtx))))
11bb1f11
JL
677 return ADDRESS_REGS;
678
4c742813
JL
679 if (GET_CODE (in) == PLUS
680 && (XEXP (in, 0) == stack_pointer_rtx
681 || XEXP (in, 1) == stack_pointer_rtx))
682 return DATA_REGS;
683
684
777fbf09
JL
685 /* Otherwise assume no secondary reloads are needed. */
686 return NO_REGS;
687}
688
689int
690initial_offset (from, to)
691 int from, to;
692{
3dbc43d1
JL
693 /* The difference between the argument pointer and the frame pointer
694 is the size of the callee register save area. */
777fbf09 695 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
11bb1f11 696 {
777fbf09
JL
697 if (regs_ever_live[2] || regs_ever_live[3]
698 || regs_ever_live[6] || regs_ever_live[7]
699 || frame_pointer_needed)
22ef4e9b 700 return 16;
777fbf09 701 else
22ef4e9b 702 return 0;
11bb1f11
JL
703 }
704
3dbc43d1
JL
705 /* The difference between the argument pointer and the stack pointer is
706 the sum of the size of this function's frame, the callee register save
707 area, and the fixed stack space needed for function calls (if any). */
777fbf09
JL
708 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
709 {
710 if (regs_ever_live[2] || regs_ever_live[3]
711 || regs_ever_live[6] || regs_ever_live[7]
712 || frame_pointer_needed)
460f4b9d
JL
713 return (get_frame_size () + 16
714 + (current_function_outgoing_args_size
715 ? current_function_outgoing_args_size + 4 : 0));
777fbf09 716 else
460f4b9d
JL
717 return (get_frame_size ()
718 + (current_function_outgoing_args_size
719 ? current_function_outgoing_args_size + 4 : 0));
777fbf09 720 }
11bb1f11 721
3dbc43d1
JL
722 /* The difference between the frame pointer and stack pointer is the sum
723 of the size of this function's frame and the fixed stack space needed
724 for function calls (if any). */
777fbf09 725 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
460f4b9d
JL
726 return (get_frame_size ()
727 + (current_function_outgoing_args_size
728 ? current_function_outgoing_args_size + 4 : 0));
777fbf09
JL
729
730 abort ();
11bb1f11 731}
22ef4e9b
JL
732
733/* Flush the argument registers to the stack for a stdarg function;
734 return the new argument pointer. */
735rtx
736mn10300_builtin_saveregs (arglist)
737 tree arglist;
738{
739 rtx offset;
740 tree fntype = TREE_TYPE (current_function_decl);
741 int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
742 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
743 != void_type_node)))
744 ? UNITS_PER_WORD : 0);
745
746 if (argadj)
747 offset = plus_constant (current_function_arg_offset_rtx, argadj);
748 else
749 offset = current_function_arg_offset_rtx;
750
751 emit_move_insn (gen_rtx (MEM, SImode, current_function_internal_arg_pointer),
752 gen_rtx (REG, SImode, 0));
753 emit_move_insn (gen_rtx (MEM, SImode,
754 plus_constant
755 (current_function_internal_arg_pointer, 4)),
756 gen_rtx (REG, SImode, 1));
757 return copy_to_reg (expand_binop (Pmode, add_optab,
758 current_function_internal_arg_pointer,
759 offset, 0, 0, OPTAB_LIB_WIDEN));
760}
761
762/* Return an RTX to represent where a value with mode MODE will be returned
763 from a function. If the result is 0, the argument is pushed. */
764
765rtx
766function_arg (cum, mode, type, named)
767 CUMULATIVE_ARGS *cum;
768 enum machine_mode mode;
769 tree type;
770 int named;
771{
772 rtx result = 0;
773 int size, align;
774
775 /* We only support using 2 data registers as argument registers. */
776 int nregs = 2;
777
778 /* Figure out the size of the object to be passed. */
779 if (mode == BLKmode)
780 size = int_size_in_bytes (type);
781 else
782 size = GET_MODE_SIZE (mode);
783
784 /* Figure out the alignment of the object to be passed. */
785 align = size;
786
787 cum->nbytes = (cum->nbytes + 3) & ~3;
788
789 /* Don't pass this arg via a register if all the argument registers
790 are used up. */
791 if (cum->nbytes > nregs * UNITS_PER_WORD)
792 return 0;
793
794 /* Don't pass this arg via a register if it would be split between
795 registers and memory. */
796 if (type == NULL_TREE
797 && cum->nbytes + size > nregs * UNITS_PER_WORD)
798 return 0;
799
800 switch (cum->nbytes / UNITS_PER_WORD)
801 {
802 case 0:
803 result = gen_rtx (REG, mode, 0);
804 break;
805 case 1:
806 result = gen_rtx (REG, mode, 1);
807 break;
808 default:
809 result = 0;
810 }
811
812 return result;
813}
814
815/* Return the number of registers to use for an argument passed partially
816 in registers and partially in memory. */
817
818int
819function_arg_partial_nregs (cum, mode, type, named)
820 CUMULATIVE_ARGS *cum;
821 enum machine_mode mode;
822 tree type;
823 int named;
824{
825 int size, align;
826
827 /* We only support using 2 data registers as argument registers. */
828 int nregs = 2;
829
830 /* Figure out the size of the object to be passed. */
831 if (mode == BLKmode)
832 size = int_size_in_bytes (type);
833 else
834 size = GET_MODE_SIZE (mode);
835
836 /* Figure out the alignment of the object to be passed. */
837 align = size;
838
839 cum->nbytes = (cum->nbytes + 3) & ~3;
840
841 /* Don't pass this arg via a register if all the argument registers
842 are used up. */
843 if (cum->nbytes > nregs * UNITS_PER_WORD)
844 return 0;
845
846 if (cum->nbytes + size <= nregs * UNITS_PER_WORD)
847 return 0;
848
849 /* Don't pass this arg via a register if it would be split between
850 registers and memory. */
851 if (type == NULL_TREE
852 && cum->nbytes + size > nregs * UNITS_PER_WORD)
853 return 0;
854
855 return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
856}
857
858/* Output a tst insn. */
859char *
860output_tst (operand, insn)
861 rtx operand, insn;
862{
22ef4e9b
JL
863 rtx temp;
864 int past_call = 0;
865
74452ac3
JL
866 /* If we have a data register which is known to be zero throughout
867 the function, then use it instead of doing a search. */
868 if (zero_dreg && REGNO_REG_CLASS (REGNO (operand)) == DATA_REGS)
869 {
870 rtx xoperands[2];
871 xoperands[0] = operand;
872 xoperands[1] = zero_dreg;
873
874 output_asm_insn ("cmp %1,%0", xoperands);
875 return "";
876 }
877
878 /* Similarly for address registers. */
879 if (zero_areg && REGNO_REG_CLASS (REGNO (operand)) == ADDRESS_REGS)
880 {
881 rtx xoperands[2];
882 xoperands[0] = operand;
883 xoperands[1] = zero_areg;
884
885 output_asm_insn ("cmp %1,%0", xoperands);
886 return "";
887 }
888
22ef4e9b
JL
889 /* We can save a byte if we can find a register which has the value
890 zero in it. */
891 temp = PREV_INSN (insn);
74452ac3 892 while (optimize && temp)
22ef4e9b
JL
893 {
894 rtx set;
895
896 /* We allow the search to go through call insns. We record
897 the fact that we've past a CALL_INSN and reject matches which
898 use call clobbered registers. */
899 if (GET_CODE (temp) == CODE_LABEL
900 || GET_CODE (temp) == JUMP_INSN
901 || GET_CODE (temp) == BARRIER)
902 break;
903
904 if (GET_CODE (temp) == CALL_INSN)
905 past_call = 1;
906
907 if (GET_CODE (temp) == NOTE)
908 {
909 temp = PREV_INSN (temp);
910 continue;
911 }
912
913 /* It must be an insn, see if it is a simple set. */
914 set = single_set (temp);
915 if (!set)
916 {
917 temp = PREV_INSN (temp);
918 continue;
919 }
920
921 /* Are we setting a data register to zero (this does not win for
922 address registers)?
923
924 If it's a call clobbered register, have we past a call?
925
926 Make sure the register we find isn't the same as ourself;
927 the mn10300 can't encode that. */
928 if (REG_P (SET_DEST (set))
929 && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set)))
930 && !reg_set_between_p (SET_DEST (set), temp, insn)
74452ac3
JL
931 && (REGNO_REG_CLASS (REGNO (SET_DEST (set)))
932 == REGNO_REG_CLASS (REGNO (operand)))
22ef4e9b
JL
933 && REGNO (SET_DEST (set)) != REGNO (operand)
934 && (!past_call
935 || !call_used_regs[REGNO (SET_DEST (set))]))
936 {
937 rtx xoperands[2];
938 xoperands[0] = operand;
939 xoperands[1] = SET_DEST (set);
940
941 output_asm_insn ("cmp %1,%0", xoperands);
942 return "";
943 }
944 temp = PREV_INSN (temp);
945 }
946 return "cmp 0,%0";
947}
460f4b9d
JL
948
949int
950impossible_plus_operand (op, mode)
951 rtx op;
952 enum machine_mode mode;
953{
954 extern rtx *reg_equiv_mem;
955 rtx reg1, reg2;
956
957 if (GET_CODE (op) != PLUS)
958 return 0;
959
4c742813
JL
960 if (XEXP (op, 0) == stack_pointer_rtx
961 || XEXP (op, 1) == stack_pointer_rtx)
460f4b9d
JL
962 return 1;
963
460f4b9d
JL
964 return 0;
965}