]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/mn10200/mn10200.c
Merge from pch-branch up to tag pch-commit-20020603.
[thirdparty/gcc.git] / gcc / config / mn10200 / mn10200.c
CommitLineData
a1c8363d 1/* Subroutines for insn-output.c for Matsushita MN10200 series
e03f5d43
KH
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
a1c8363d
JL
4 Contributed by Jeff Law (law@cygnus.com).
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
22
a1c8363d 23#include "config.h"
c5c76735 24#include "system.h"
a1c8363d 25#include "rtl.h"
bf6bb899 26#include "tree.h"
a1c8363d
JL
27#include "regs.h"
28#include "hard-reg-set.h"
29#include "real.h"
30#include "insn-config.h"
31#include "conditions.h"
a1c8363d
JL
32#include "output.h"
33#include "insn-attr.h"
34#include "flags.h"
35#include "recog.h"
36#include "expr.h"
bf6bb899 37#include "function.h"
a1c8363d 38#include "obstack.h"
b979ef45 39#include "ggc.h"
ac42d1e9
KG
40#include "toplev.h"
41#include "tm_p.h"
672a6f42
NB
42#include "target.h"
43#include "target-def.h"
a1c8363d
JL
44
45/* Global registers known to hold the value zero.
46
47 Normally we'd depend on CSE and combine to put zero into a
48 register and re-use it.
49
50 However, on the mn10x00 processors we implicitly use the constant
51 zero in tst instructions, so we might be able to do better by
52 loading the value into a register in the prologue, then re-useing
53 that register throughout the function.
54
55 We could perform similar optimizations for other constants, but with
56 gcse due soon, it doesn't seem worth the effort.
57
58 These variables hold a rtx for a register known to hold the value
59 zero throughout the entire function, or NULL if no register of
60 the appropriate class has such a value throughout the life of the
61 function. */
62rtx zero_dreg;
63rtx zero_areg;
64
ac42d1e9
KG
65static void count_tst_insns PARAMS ((int *));
66
a1c8363d
JL
67/* Note whether or not we need an out of line epilogue. */
68static int out_of_line_epilogue;
672a6f42
NB
69\f
70/* Initialize the GCC target structure. */
301d03af
RS
71#undef TARGET_ASM_ALIGNED_HI_OP
72#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
a1c8363d 73
f6897b10 74struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 75\f
a1c8363d
JL
76/* Indicate this file was compiled by gcc and what optimization
77 level was used. */
78void
79asm_file_start (file)
80 FILE *file;
81{
82 fprintf (file, "#\tGCC For the Matsushita MN10200\n");
83 if (optimize)
84 fprintf (file, "# -O%d\n", optimize);
85 else
86 fprintf (file, "\n\n");
87 output_file_directive (file, main_input_filename);
88}
89
90/* Print operand X using operand code CODE to assembly language output file
91 FILE. */
92
93void
94print_operand (file, x, code)
95 FILE *file;
96 rtx x;
97 int code;
98{
99 switch (code)
100 {
101 case 'b':
102 case 'B':
103 /* These are normal and reversed branches. */
104 switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
105 {
106 case NE:
107 fprintf (file, "ne");
108 break;
109 case EQ:
110 fprintf (file, "eq");
111 break;
112 case GE:
113 fprintf (file, "ge");
114 break;
115 case GT:
116 fprintf (file, "gt");
117 break;
118 case LE:
119 fprintf (file, "le");
120 break;
121 case LT:
122 fprintf (file, "lt");
123 break;
124 case GEU:
125 fprintf (file, "cc");
126 break;
127 case GTU:
128 fprintf (file, "hi");
129 break;
130 case LEU:
131 fprintf (file, "ls");
132 break;
133 case LTU:
134 fprintf (file, "cs");
135 break;
136 default:
137 abort ();
138 }
139 break;
140 case 'C':
141 /* This is used for the operand to a call instruction;
142 if it's a REG, enclose it in parens, else output
143 the operand normally. */
144 if (GET_CODE (x) == REG)
145 {
146 fputc ('(', file);
147 print_operand (file, x, 0);
148 fputc (')', file);
149 }
150 else
151 print_operand (file, x, 0);
152 break;
153
154 /* These are the least significant word in a 32bit value.
155 'o' allows us to sign extend a constant if doing so
156 makes for more compact code. */
157 case 'L':
158 case 'o':
159 switch (GET_CODE (x))
160 {
161 case MEM:
162 fputc ('(', file);
163 output_address (XEXP (x, 0));
164 fputc (')', file);
165 break;
166
167 case REG:
168 fprintf (file, "%s", reg_names[REGNO (x)]);
169 break;
170
171 case SUBREG:
ddef6bc7 172 fprintf (file, "%s", reg_names[subreg_regno (x)]);
a1c8363d
JL
173 break;
174
175 case CONST_DOUBLE:
176 if (code == 'L')
177 {
178 long val;
179 REAL_VALUE_TYPE rv;
180
181 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
182 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
183 print_operand_address (file, GEN_INT (val & 0xffff));
184 }
185 else
186 {
187 long val;
188 REAL_VALUE_TYPE rv;
189
190 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
191 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
192
193 val &= 0xffff;
194 val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
195 print_operand_address (file, GEN_INT (val));
196 }
197 break;
198
199 case CONST_INT:
200 if (code == 'L')
201 print_operand_address (file, GEN_INT ((INTVAL (x) & 0xffff)));
202 else
203 {
204 unsigned int val = INTVAL (x) & 0xffff;
205 val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
206 print_operand_address (file, GEN_INT (val));
207 }
208 break;
209 default:
210 abort ();
211 }
212 break;
213
214 /* Similarly, but for the most significant word. */
215 case 'H':
216 case 'h':
217 switch (GET_CODE (x))
218 {
219 case MEM:
220 fputc ('(', file);
b72f00af 221 x = adjust_address (x, HImode, 2);
a1c8363d
JL
222 output_address (XEXP (x, 0));
223 fputc (')', file);
224 break;
225
226 case REG:
227 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
228 break;
229
230 case SUBREG:
ddef6bc7 231 fprintf (file, "%s", reg_names[subreg_regno (x) + 1]);
a1c8363d
JL
232 break;
233
234 case CONST_DOUBLE:
235 if (code == 'H')
236 {
237 long val;
238 REAL_VALUE_TYPE rv;
239
240 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
241 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
242
243 print_operand_address (file, GEN_INT ((val >> 16) & 0xffff));
244 }
245 else
246 {
247 long val;
248 REAL_VALUE_TYPE rv;
249
250 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
251 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
252
253 val = (val >> 16) & 0xffff;
254 val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
255
256 print_operand_address (file, GEN_INT (val));
257 }
258 break;
259
260 case CONST_INT:
261 if (code == 'H')
262 print_operand_address (file,
263 GEN_INT ((INTVAL (x) >> 16) & 0xffff));
264 else
265 {
266 unsigned int val = (INTVAL (x) >> 16) & 0xffff;
267 val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
268
269 print_operand_address (file, GEN_INT (val));
270 }
271 break;
272 default:
273 abort ();
274 }
275 break;
276
277 /* Output ~CONST_INT. */
278 case 'N':
279 if (GET_CODE (x) != CONST_INT)
280 abort ();
281 fprintf (file, "%d", ~INTVAL (x));
282 break;
283
284 /* An address which can not be register indirect, if it is
285 register indirect, then turn it into reg + disp. */
286 case 'A':
287 if (GET_CODE (x) != MEM)
288 abort ();
289 if (GET_CODE (XEXP (x, 0)) == REG)
c5c76735 290 x = gen_rtx_PLUS (PSImode, XEXP (x, 0), GEN_INT (0));
a1c8363d
JL
291 else
292 x = XEXP (x, 0);
293 fputc ('(', file);
294 output_address (x);
295 fputc (')', file);
296 break;
297
298 case 'Z':
299 print_operand (file, XEXP (x, 1), 0);
300 break;
301
302 /* More cases where we can sign-extend a CONST_INT if it
303 results in more compact code. */
304 case 's':
305 case 'S':
306 if (GET_CODE (x) == CONST_INT)
307 {
308 int val = INTVAL (x);
309
310 if (code == 's')
311 x = GEN_INT (((val & 0xffff) ^ (~0x7fff)) + 0x8000);
312 else
313 x = GEN_INT (((val & 0xff) ^ (~0x7f)) + 0x80);
314 }
315 /* FALL THROUGH */
316 default:
317 switch (GET_CODE (x))
318 {
319 case MEM:
320 fputc ('(', file);
321 output_address (XEXP (x, 0));
322 fputc (')', file);
323 break;
324
325 case REG:
326 fprintf (file, "%s", reg_names[REGNO (x)]);
327 break;
328
329 case SUBREG:
ddef6bc7 330 fprintf (file, "%s", reg_names[subreg_regno (x)]);
a1c8363d
JL
331 break;
332
333 case CONST_INT:
334 case CONST_DOUBLE:
335 case SYMBOL_REF:
336 case CONST:
337 case LABEL_REF:
338 case CODE_LABEL:
339 print_operand_address (file, x);
340 break;
341 default:
342 abort ();
343 }
344 break;
345 }
346}
347
348/* Output assembly language output for the address ADDR to FILE. */
349
350void
351print_operand_address (file, addr)
352 FILE *file;
353 rtx addr;
354{
355 switch (GET_CODE (addr))
356 {
357 case REG:
358 print_operand (file, addr, 0);
359 break;
360 case PLUS:
361 {
362 rtx base, index;
363 /* The base and index could be in any order, so we have
364 to figure out which is the base and which is the index.
365 Uses the same code as GO_IF_LEGITIMATE_ADDRESS. */
366 if (REG_P (XEXP (addr, 0))
367 && REG_OK_FOR_BASE_P (XEXP (addr, 0)))
368 base = XEXP (addr, 0), index = XEXP (addr, 1);
369 else if (REG_P (XEXP (addr, 1))
370 && REG_OK_FOR_BASE_P (XEXP (addr, 1)))
371 base = XEXP (addr, 1), index = XEXP (addr, 0);
372 else
373 abort ();
374 print_operand (file, index, 0);
375 fputc (',', file);
376 print_operand (file, base, 0);;
377 break;
378 }
379 case SYMBOL_REF:
380 output_addr_const (file, addr);
381 break;
382 default:
383 output_addr_const (file, addr);
384 break;
385 }
386}
387
388/* Count the number of tst insns which compare an address register
389 with zero. */
390static void
391count_tst_insns (areg_countp)
392 int *areg_countp;
393{
394 rtx insn;
395
396 /* Assume no tst insns exist. */
397 *areg_countp = 0;
398
399 /* If not optimizing, then quit now. */
400 if (!optimize)
401 return;
402
403 /* Walk through all the insns. */
404 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
405 {
406 rtx pat;
407
408 /* Ignore anything that is not a normal INSN. */
409 if (GET_CODE (insn) != INSN)
410 continue;
411
412 /* Ignore anything that isn't a SET. */
413 pat = PATTERN (insn);
414 if (GET_CODE (pat) != SET)
415 continue;
416
417 /* Check for a tst insn. */
418 if (SET_DEST (pat) == cc0_rtx
419 && GET_CODE (SET_SRC (pat)) == REG
420 && REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == ADDRESS_REGS)
421 (*areg_countp)++;
422 }
423}
424
425/* Return the total size (in bytes) of the current function's frame.
426 This is the size of the register save area + the size of locals,
427 spills, etc. */
428int
429total_frame_size ()
430{
431 unsigned int size = get_frame_size ();
432 unsigned int outgoing_args_size = current_function_outgoing_args_size;
433 int i;
434
435 /* First figure out if we're going to use an out of line
436 prologue, if so we have to make space for all the
437 registers, even if we don't use them. */
438 if (optimize && !current_function_needs_context && !frame_pointer_needed)
439 {
440 int inline_count, outline_count;
441
442 /* Compute how many bytes an inline prologue would take.
443
444 Each address register store takes two bytes, each data register
445 store takes three bytes. */
446 inline_count = 0;
447 if (regs_ever_live[5])
448 inline_count += 2;
449 if (regs_ever_live[6])
450 inline_count += 2;
451 if (regs_ever_live[2])
452 inline_count += 3;
453 if (regs_ever_live[3])
454 inline_count += 3;
455
456 /* If this function has any stack, then the stack adjustment
457 will take two (or more) bytes. */
458 if (size || outgoing_args_size
459 || regs_ever_live[5] || regs_ever_live[6]
460 || regs_ever_live[2] || regs_ever_live[3])
461 inline_count += 2;
462
463 /* Multiply the current count by two and add one to account for the
464 epilogue insns. */
465 inline_count = inline_count * 2 + 1;
466
467 /* Now compute how many bytes an out of line sequence would take. */
468 /* A relaxed jsr will be three bytes. */
469 outline_count = 3;
470
471 /* If there are outgoing arguments, then we will need a stack
472 pointer adjustment after the call to the prologue, two
473 more bytes. */
474 outline_count += (outgoing_args_size == 0 ? 0 : 2);
475
476 /* If there is some local frame to allocate, it will need to be
477 done before the call to the prologue, two more bytes. */
478 if (get_frame_size () != 0)
479 outline_count += 2;
480
481 /* Now account for the epilogue, multiply the base count by two,
482 then deal with optimizing away the rts instruction. */
483 outline_count = outline_count * 2 + 1;
484
485 if (get_frame_size () == 0 && outgoing_args_size == 0)
486 outline_count -= 1;
487
488 /* If an out of line prologue is smaller, use it. */
489 if (inline_count > outline_count)
490 return size + outgoing_args_size + 16;
491 }
492
493
494 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
495 {
ac42d1e9 496 if ((regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i])
a1c8363d
JL
497 || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
498 size += 4;
499 }
500
501 return (size + outgoing_args_size);
502}
503
504/* Expand the prologue into RTL. */
505void
506expand_prologue ()
507{
508 unsigned int size = total_frame_size ();
509 unsigned int outgoing_args_size = current_function_outgoing_args_size;
510 int offset, i;
511
512 zero_areg = NULL_RTX;
513 zero_dreg = NULL_RTX;
514
515 /* If optimizing, see if we should do an out of line prologue/epilogue
516 sequence.
517
518 We don't support out of line prologues if the current function
519 needs a context or frame pointer. */
520 if (optimize && !current_function_needs_context && !frame_pointer_needed)
521 {
522 int inline_count, outline_count, areg_count;
523
524 /* We need to end the current sequence so that count_tst_insns can
525 look at all the insns in this function. Normally this would be
526 unsafe, but it's OK in the prologue/epilogue expanders. */
527 end_sequence ();
528
529 /* Get a count of the number of tst insns which use address
530 registers (it's not profitable to try and improve tst insns
531 which use data registers). */
532 count_tst_insns (&areg_count);
533
534 /* Now start a new sequence. */
535 start_sequence ();
536
537 /* Compute how many bytes an inline prologue would take.
538
539 Each address register store takes two bytes, each data register
540 store takes three bytes. */
541 inline_count = 0;
542 if (regs_ever_live[5])
543 inline_count += 2;
544 if (regs_ever_live[6])
545 inline_count += 2;
546 if (regs_ever_live[2])
547 inline_count += 3;
548 if (regs_ever_live[3])
549 inline_count += 3;
550
551 /* If this function has any stack, then the stack adjustment
552 will take two (or more) bytes. */
553 if (size || outgoing_args_size
554 || regs_ever_live[5] || regs_ever_live[6]
555 || regs_ever_live[2] || regs_ever_live[3])
556 inline_count += 2;
557
558 /* Multiply the current count by two and add one to account for the
559 epilogue insns. */
560 inline_count = inline_count * 2 + 1;
561
562 /* Now compute how many bytes an out of line sequence would take. */
563 /* A relaxed jsr will be three bytes. */
564 outline_count = 3;
565
566 /* If there are outgoing arguments, then we will need a stack
567 pointer adjustment after the call to the prologue, two
568 more bytes. */
569 outline_count += (outgoing_args_size == 0 ? 0 : 2);
570
571 /* If there is some local frame to allocate, it will need to be
572 done before the call to the prologue, two more bytes. */
573 if (get_frame_size () != 0)
574 outline_count += 2;
575
576 /* Now account for the epilogue, multiply the base count by two,
577 then deal with optimizing away the rts instruction. */
578 outline_count = outline_count * 2 + 1;
579
580 if (get_frame_size () == 0 && outgoing_args_size == 0)
581 outline_count -= 1;
582
583 /* If an out of line prologue is smaller, use it. */
584 if (inline_count > outline_count)
585 {
586 if (get_frame_size () != 0)
587 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
588 GEN_INT (-size + outgoing_args_size + 16)));
589 emit_insn (gen_outline_prologue_call ());
590
591 if (outgoing_args_size)
592 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
593 GEN_INT (-outgoing_args_size)));
594
595 out_of_line_epilogue = 1;
596
597 /* Determine if it is profitable to put the value zero into a register
598 for the entire function. If so, set ZERO_DREG and ZERO_AREG. */
599
600 /* First see if we could load the value into a data register
601 since that's the most efficient way. */
602 if (areg_count > 1
603 && (!regs_ever_live[2] || !regs_ever_live[3]))
604 {
605 if (!regs_ever_live[2])
606 {
607 regs_ever_live[2] = 1;
c5c76735 608 zero_dreg = gen_rtx_REG (HImode, 2);
a1c8363d
JL
609 }
610 if (!regs_ever_live[3])
611 {
612 regs_ever_live[3] = 1;
c5c76735 613 zero_dreg = gen_rtx_REG (HImode, 3);
a1c8363d
JL
614 }
615 }
616
e03f5d43 617 /* Now see if we could load the value into an address register. */
a1c8363d
JL
618 if (zero_dreg == NULL_RTX
619 && areg_count > 2
620 && (!regs_ever_live[5] || !regs_ever_live[6]))
621 {
622 if (!regs_ever_live[5])
623 {
624 regs_ever_live[5] = 1;
c5c76735 625 zero_areg = gen_rtx_REG (HImode, 5);
a1c8363d
JL
626 }
627 if (!regs_ever_live[6])
628 {
629 regs_ever_live[6] = 1;
c5c76735 630 zero_areg = gen_rtx_REG (HImode, 6);
a1c8363d
JL
631 }
632 }
633
634 if (zero_dreg)
635 emit_move_insn (zero_dreg, const0_rtx);
636
637 if (zero_areg)
638 emit_move_insn (zero_areg, const0_rtx);
639
640 return;
641 }
642 }
643
644 out_of_line_epilogue = 0;
645
646 /* Temporarily stuff the static chain onto the stack so we can
647 use a0 as a scratch register during the prologue. */
648 if (current_function_needs_context)
649 {
650 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
651 GEN_INT (-4)));
c5c76735
JL
652 emit_move_insn (gen_rtx_MEM (PSImode, stack_pointer_rtx),
653 gen_rtx_REG (PSImode, STATIC_CHAIN_REGNUM));
a1c8363d
JL
654 }
655
656 if (frame_pointer_needed)
657 {
658 /* Store a2 into a0 temporarily. */
c5c76735 659 emit_move_insn (gen_rtx_REG (PSImode, 4), frame_pointer_rtx);
a1c8363d
JL
660
661 /* Set up the frame pointer. */
662 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
663 }
664
665 /* Make any necessary space for the saved registers and local frame. */
666 if (size)
667 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
668 GEN_INT (-size)));
669
670 /* Save the callee saved registers. They're saved into the top
671 of the frame, using the stack pointer. */
672 for (i = 0, offset = outgoing_args_size;
673 i < FIRST_PSEUDO_REGISTER; i++)
674 {
ac42d1e9 675 if ((regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i])
a1c8363d
JL
676 || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
677 {
678 int regno;
679
680 /* If we're saving the frame pointer, then it will be found in
681 register 4 (a0). */
682 regno = (i == FRAME_POINTER_REGNUM && frame_pointer_needed) ? 4 : i;
683
c5c76735
JL
684 emit_move_insn (gen_rtx_MEM (PSImode,
685 plus_constant (stack_pointer_rtx,
686 offset)),
687 gen_rtx_REG (PSImode, regno));
a1c8363d
JL
688 offset += 4;
689 }
690 }
691
692 /* Now put the static chain back where the rest of the function
693 expects to find it. */
694 if (current_function_needs_context)
695 {
c5c76735 696 emit_move_insn (gen_rtx_REG (PSImode, STATIC_CHAIN_REGNUM),
a1c8363d 697 gen_rtx (MEM, PSImode,
c5c76735
JL
698 gen_rtx_PLUS (PSImode, stack_pointer_rtx,
699 GEN_INT (size))));
a1c8363d
JL
700 }
701}
702
703/* Expand the epilogue into RTL. */
704void
705expand_epilogue ()
706{
707 unsigned int size;
708 unsigned int outgoing_args_size = current_function_outgoing_args_size;
709 int offset, i, temp_regno;
710 rtx basereg;
711
712 size = total_frame_size ();
713
714 if (DECL_RESULT (current_function_decl)
715 && DECL_RTL (DECL_RESULT (current_function_decl))
716 && REG_P (DECL_RTL (DECL_RESULT (current_function_decl))))
717 temp_regno = (REGNO (DECL_RTL (DECL_RESULT (current_function_decl))) == 4
718 ? 0 : 4);
719 else
720 temp_regno = 4;
721
722 /* Emit an out of line epilogue sequence if it's profitable to do so. */
723 if (out_of_line_epilogue)
724 {
725 /* If there were no outgoing arguments and no local frame, then
726 we will be able to omit the rts at the end of this function,
727 so just jump to the epilogue_noreturn routine. */
728 if (get_frame_size () == 0 && outgoing_args_size == 0)
729 {
730 emit_jump_insn (gen_outline_epilogue_jump ());
731 return;
732 }
733
734 if (outgoing_args_size)
735 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
736 GEN_INT (outgoing_args_size)));
737
738 if (temp_regno == 0)
739 emit_insn (gen_outline_epilogue_call_d0 ());
740 else if (temp_regno == 4)
741 emit_insn (gen_outline_epilogue_call_a0 ());
742
743 if (get_frame_size () != 0)
744 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
745 GEN_INT (size - outgoing_args_size - 16)));
746 emit_jump_insn (gen_return_internal ());
747 return;
748 }
749
750 /* Registers are restored from the frame pointer if we have one,
751 else they're restored from the stack pointer. Figure out
752 the appropriate offset to the register save area for both cases. */
753 if (frame_pointer_needed)
754 {
755 basereg = frame_pointer_rtx;
756 offset = -(size - outgoing_args_size);
757 }
758 else
759 {
760 basereg = stack_pointer_rtx;
761 offset = outgoing_args_size;
762 }
763
764 /* Restore each register. */
765 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
766 {
ac42d1e9 767 if ((regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i])
a1c8363d
JL
768 || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
769 {
770 int regno;
771
772 /* Restore the frame pointer (if it exists) into a temporary
773 register. */
774 regno = ((i == FRAME_POINTER_REGNUM && frame_pointer_needed)
775 ? temp_regno : i);
776
c5c76735
JL
777 emit_move_insn (gen_rtx_REG (PSImode, regno),
778 gen_rtx_MEM (PSImode,
779 plus_constant (basereg, offset)));
a1c8363d
JL
780 offset += 4;
781 }
782 }
783
784 if (frame_pointer_needed)
785 {
786 /* Deallocate this frame's stack. */
787 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
788 /* Restore the old frame pointer. */
c5c76735 789 emit_move_insn (frame_pointer_rtx, gen_rtx_REG (PSImode, temp_regno));
a1c8363d
JL
790 }
791 else if (size)
792 {
793 /* Deallocate this function's stack. */
794 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
795 GEN_INT (size)));
796 }
797
798 /* If we had to allocate a slot to save the context pointer,
799 then it must be deallocated here. */
800 if (current_function_needs_context)
801 emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4)));
802
803 /* Emit the return insn, if this function had no stack, then we
804 can use the standard return (which allows more optimizations),
805 else we have to use the special one which inhibits optimizations. */
806 if (size == 0 && !current_function_needs_context)
807 emit_jump_insn (gen_return ());
808 else
809 emit_jump_insn (gen_return_internal ());
810}
811
812/* Update the condition code from the insn. */
813
814void
815notice_update_cc (body, insn)
816 rtx body;
817 rtx insn;
818{
819 switch (get_attr_cc (insn))
820 {
821 case CC_NONE:
822 /* Insn does not affect CC at all. */
823 break;
824
825 case CC_NONE_0HIT:
826 /* Insn does not change CC, but the 0'th operand has been changed. */
827 if (cc_status.value1 != 0
1ccbefce 828 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
a1c8363d
JL
829 cc_status.value1 = 0;
830 break;
831
832 case CC_SET_ZN:
1ccbefce 833 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
a1c8363d
JL
834 V,C is in an unusable state. */
835 CC_STATUS_INIT;
836 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1ccbefce 837 cc_status.value1 = recog_data.operand[0];
a1c8363d
JL
838 break;
839
840 case CC_SET_ZNV:
1ccbefce 841 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
a1c8363d
JL
842 C is in an unusable state. */
843 CC_STATUS_INIT;
844 cc_status.flags |= CC_NO_CARRY;
1ccbefce 845 cc_status.value1 = recog_data.operand[0];
a1c8363d
JL
846 break;
847
848 case CC_COMPARE:
849 /* The insn is a compare instruction. */
850 CC_STATUS_INIT;
851 cc_status.value1 = SET_SRC (body);
852 break;
853
854 case CC_CLOBBER:
855 /* Insn doesn't leave CC in a usable state. */
856 CC_STATUS_INIT;
857 break;
858
859 default:
860 CC_STATUS_INIT;
861 break;
862 }
863}
864
865/* Return true if OP is a valid call operand. Valid call operands
866 are SYMBOL_REFs and REGs. */
867int
868call_address_operand (op, mode)
869 rtx op;
ac42d1e9 870 enum machine_mode mode ATTRIBUTE_UNUSED;
a1c8363d
JL
871{
872 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
a1c8363d
JL
873}
874
875/* Return true if OP is a memory operand with a constant address.
876 A special PSImode move pattern uses this predicate. */
877int
878constant_memory_operand (op, mode)
879 rtx op;
ac42d1e9 880 enum machine_mode mode ATTRIBUTE_UNUSED;
a1c8363d
JL
881{
882 return GET_CODE (op) == MEM && CONSTANT_ADDRESS_P (XEXP (op, 0));
883}
884
4c82e145
NC
885/* Return true if OP is valid for a psi mode truncation operand.
886 It must either be a memory operand which is valid for a PSImode
887 address, or if it is not a memory operand at all. */
888int
889psimode_truncation_operand (op, mode)
890 rtx op;
891 enum machine_mode mode;
892{
893 return (general_operand (op, mode)
894 && (GET_CODE (op) != MEM
895 || memory_address_p (PSImode, XEXP (op, 0))));
896}
897
a1c8363d
JL
898/* What (if any) secondary registers are needed to move IN with mode
899 MODE into a register from in register class CLASS.
900
901 We might be able to simplify this. */
902enum reg_class
903secondary_reload_class (class, mode, in, input)
904 enum reg_class class;
905 enum machine_mode mode;
906 rtx in;
907 int input;
908{
a1c8363d
JL
909 /* Memory loads less than a full word wide can't have an
910 address or stack pointer destination. They must use
911 a data register as an intermediate register. */
912 if (input
913 && GET_CODE (in) == MEM
914 && (mode == QImode)
915 && class == ADDRESS_REGS)
916 return DATA_REGS;
917
956d6950 918 /* Address register stores which are not PSImode need a scratch register. */
a1c8363d
JL
919 if (! input
920 && GET_CODE (in) == MEM
921 && (mode != PSImode)
922 && class == ADDRESS_REGS)
923 return DATA_REGS;
924
925 /* Otherwise assume no secondary reloads are needed. */
926 return NO_REGS;
927}
928
929\f
930/* Shifts.
931
932 We devote a fair bit of code to getting efficient shifts since we can only
933 shift one bit at a time, and each single bit shift may take multiple
934 instructions.
935
936 The basic shift methods:
937
938 * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
939 this is the default. SHIFT_LOOP
940
941 * inlined shifts -- emit straight line code for the shift; this is
942 used when a straight line shift is about the same size or smaller
943 than a loop. We allow the inline version to be slightly longer in
944 some cases as it saves a register. SHIFT_INLINE
945
946 * There other oddballs. Not worth explaining. SHIFT_SPECIAL
947
948
949 HImode shifts:
950
951 1-4 do them inline
952
953 5-7 If ashift, then multiply, else loop.
954
955 8-14 - If ashift, then multiply, if lshiftrt, then divide, else loop.
956 15 - rotate the bit we want into the carry, clear the destination,
957 (use mov 0,dst, not sub as sub will clobber the carry), then
958 move bit into place.
959
960 Don't Panic, it's not nearly as bad as the H8 shifting code!!! */
961
962int
963nshift_operator (x, mode)
964 rtx x;
ac42d1e9 965 enum machine_mode mode ATTRIBUTE_UNUSED;
a1c8363d
JL
966{
967 switch (GET_CODE (x))
968 {
969 case ASHIFTRT:
970 case LSHIFTRT:
971 case ASHIFT:
972 return 1;
973
974 default:
975 return 0;
976 }
977}
978
979/* Called from the .md file to emit code to do shifts.
980 Returns a boolean indicating success
981 (currently this is always TRUE). */
982
983int
984expand_a_shift (mode, code, operands)
985 enum machine_mode mode;
986 int code;
987 rtx operands[];
988{
989 emit_move_insn (operands[0], operands[1]);
990
991 /* need a loop to get all the bits we want - we generate the
992 code at emit time, but need to allocate a scratch reg now */
993
c5c76735
JL
994 emit_insn (gen_rtx_PARALLEL
995 (VOIDmode,
a1c8363d 996 gen_rtvec (2,
c5c76735
JL
997 gen_rtx_SET (VOIDmode, operands[0],
998 gen_rtx (code, mode,
999 operands[0], operands[2])),
1000 gen_rtx_CLOBBER (VOIDmode,
1001 gen_rtx_SCRATCH (HImode)))));
a1c8363d
JL
1002
1003 return 1;
1004}
1005
1006/* Shift algorithm determination.
1007
1008 There are various ways of doing a shift:
1009 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1010 shifts as we need.
1011 SHIFT_SPECIAL: Hand crafted assembler.
1012 SHIFT_LOOP: If the above methods fail, just loop. */
1013
1014enum shift_alg
1015{
1016 SHIFT_INLINE,
1017 SHIFT_SPECIAL,
1018 SHIFT_LOOP,
1019 SHIFT_MAX
1020};
1021
1022/* Symbols of the various shifts which can be used as indices. */
1023
1024enum shift_type
1025 {
1026 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1027 };
1028
1029/* Symbols of the various modes which can be used as indices. */
1030
1031enum shift_mode
1032 {
1943c2c1 1033 HIshift
a1c8363d
JL
1034 };
1035
1036/* For single bit shift insns, record assembler and what bits of the
1037 condition code are valid afterwards (represented as various CC_FOO
1038 bits, 0 means CC isn't left in a usable state). */
1039
1040struct shift_insn
1041{
ac42d1e9 1042 const char *assembler;
a1c8363d
JL
1043 int cc_valid;
1044};
1045
1046/* Assembler instruction shift table.
1047
1048 These tables are used to look up the basic shifts.
1049 They are indexed by cpu, shift_type, and mode.
1050*/
1051
1052static const struct shift_insn shift_one[3][3] =
1053{
1054 {
1055/* SHIFT_ASHIFT */
1056 { "add\t%0,%0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1057 },
1058/* SHIFT_LSHIFTRT */
1059 {
1060 { "lsr\t%0", CC_NO_CARRY },
1061 },
1062/* SHIFT_ASHIFTRT */
1063 {
1064 { "asr\t%0", CC_NO_CARRY },
1065 },
1066};
1067
ac42d1e9
KG
1068static enum shift_alg get_shift_alg PARAMS ((enum shift_type,
1069 enum machine_mode, int,
1070 const char **, int *));
1071
a1c8363d
JL
1072/* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
1073 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
1074 We don't achieve maximum efficiency in all cases, but the hooks are here
1075 to do so.
1076
1077 For now we just use lots of switch statements. Since we don't even come
1078 close to supporting all the cases, this is simplest. If this function ever
1079 gets too big, perhaps resort to a more table based lookup. Of course,
1080 at this point you may just wish to do it all in rtl. */
1081
1082static enum shift_alg
1083get_shift_alg (shift_type, mode, count, assembler_p, cc_valid_p)
1084 enum shift_type shift_type;
1085 enum machine_mode mode;
1086 int count;
1087 const char **assembler_p;
1088 int *cc_valid_p;
1089{
1090 /* The default is to loop. */
1091 enum shift_alg alg = SHIFT_LOOP;
1092 enum shift_mode shift_mode;
1093
1094 /* We don't handle negative shifts or shifts greater than the word size,
1095 they should have been handled already. */
1096
1097 if (count < 0 || count > GET_MODE_BITSIZE (mode))
1098 abort ();
1099
1100 switch (mode)
1101 {
1102 case HImode:
1103 shift_mode = HIshift;
1104 break;
1105 default:
1106 abort ();
1107 }
1108
1109 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
1110 It is up to the caller to know that looping clobbers cc. */
1111 *assembler_p = shift_one[shift_type][shift_mode].assembler;
1112 *cc_valid_p = shift_one[shift_type][shift_mode].cc_valid;
1113
1114 /* Now look for cases we want to optimize. */
1115
1116 switch (shift_mode)
1117 {
1118 case HIshift:
1119 if (count <= 4)
1120 return SHIFT_INLINE;
1121 else if (count < 15 && shift_type != SHIFT_ASHIFTRT)
1122 {
1123 switch (count)
1124 {
1125 case 5:
1126 if (shift_type == SHIFT_ASHIFT)
1127 *assembler_p = "mov 32,%4\n\tmul %4,%0";
1128 else if (shift_type == SHIFT_LSHIFTRT)
1129 *assembler_p
1130 = "sub %4,%4\n\tmov %4,mdr\n\tmov 32,%4\n\tdivu %4,%0";
1131 *cc_valid_p = CC_NO_CARRY;
1132 return SHIFT_SPECIAL;
1133 case 6:
1134 if (shift_type == SHIFT_ASHIFT)
1135 *assembler_p = "mov 64,%4\n\tmul %4,%0";
1136 else if (shift_type == SHIFT_LSHIFTRT)
1137 *assembler_p
1138 = "sub %4,%4\n\tmov %4,mdr\n\tmov 64,%4\n\tdivu %4,%0";
1139 *cc_valid_p = CC_NO_CARRY;
1140 return SHIFT_SPECIAL;
1141 case 7:
1142 if (shift_type == SHIFT_ASHIFT)
1143 *assembler_p = "mov 128,%4\n\tmul %4,%0";
1144 else if (shift_type == SHIFT_LSHIFTRT)
1145 *assembler_p
1146 = "sub %4,%4\n\tmov %4,mdr\n\tmov 128,%4\n\tdivu %4,%0";
1147 *cc_valid_p = CC_NO_CARRY;
1148 return SHIFT_SPECIAL;
1149 case 8:
1150 if (shift_type == SHIFT_ASHIFT)
1151 *assembler_p = "mov 256,%4\n\tmul %4,%0";
1152 else if (shift_type == SHIFT_LSHIFTRT)
1153 *assembler_p
1154 = "sub %4,%4\n\tmov %4,mdr\n\tmov 256,%4\n\tdivu %4,%0";
1155 *cc_valid_p = CC_NO_CARRY;
1156 return SHIFT_SPECIAL;
1157 case 9:
1158 if (shift_type == SHIFT_ASHIFT)
1159 *assembler_p = "mov 512,%4\n\tmul %4,%0";
1160 else if (shift_type == SHIFT_LSHIFTRT)
1161 *assembler_p
1162 = "sub %4,%4\n\tmov %4,mdr\n\tmov 512,%4\n\tdivu %4,%0";
1163 *cc_valid_p = CC_NO_CARRY;
1164 return SHIFT_SPECIAL;
1165 case 10:
1166 if (shift_type == SHIFT_ASHIFT)
1167 *assembler_p = "mov 1024,%4\n\tmul %4,%0";
1168 else if (shift_type == SHIFT_LSHIFTRT)
1169 *assembler_p
1170 = "sub %4,%4\n\tmov %4,mdr\n\tmov 1024,%4\n\tdivu %4,%0";
1171 *cc_valid_p = CC_NO_CARRY;
1172 return SHIFT_SPECIAL;
1173 case 11:
1174 if (shift_type == SHIFT_ASHIFT)
1175 *assembler_p = "mov 2048,%4\n\tmul %4,%0";
1176 else if (shift_type == SHIFT_LSHIFTRT)
1177 *assembler_p
1178 = "sub %4,%4\n\tmov %4,mdr\n\tmov 2048,%4\n\tdivu %4,%0";
1179 *cc_valid_p = CC_NO_CARRY;
1180 return SHIFT_SPECIAL;
1181 case 12:
1182 if (shift_type == SHIFT_ASHIFT)
1183 *assembler_p = "mov 4096,%4\n\tmul %4,%0";
1184 else if (shift_type == SHIFT_LSHIFTRT)
1185 *assembler_p
1186 = "sub %4,%4\n\tmov %4,mdr\n\tmov 4096,%4\n\tdivu %4,%0";
1187 *cc_valid_p = CC_NO_CARRY;
1188 return SHIFT_SPECIAL;
1189 case 13:
1190 if (shift_type == SHIFT_ASHIFT)
1191 *assembler_p = "mov 8192,%4\n\tmul %4,%0";
1192 else if (shift_type == SHIFT_LSHIFTRT)
1193 *assembler_p
1194 = "sub %4,%4\n\tmov %4,mdr\n\tmov 8192,%4\n\tdivu %4,%0";
1195 *cc_valid_p = CC_NO_CARRY;
1196 return SHIFT_SPECIAL;
1197 case 14:
1198 if (shift_type == SHIFT_ASHIFT)
1199 *assembler_p = "mov 16384,%4\n\tmul %4,%0";
1200 else if (shift_type == SHIFT_LSHIFTRT)
1201 *assembler_p
1202 = "sub %4,%4\n\tmov %4,mdr\n\tmov 16384,%4\n\tdivu %4,%0";
1203 *cc_valid_p = CC_NO_CARRY;
1204 return SHIFT_SPECIAL;
1205 }
1206 }
1207 else if (count == 15)
1208 {
1209 if (shift_type == SHIFT_ASHIFTRT)
1210 {
1211 *assembler_p = "add\t%0,%0\n\tsubc\t%0,%0\n";
1212 *cc_valid_p = CC_NO_CARRY;
1213 return SHIFT_SPECIAL;
1214 }
1215 if (shift_type == SHIFT_LSHIFTRT)
1216 {
1217 *assembler_p = "add\t%0,%0\n\tmov 0,%0\n\trol %0\n";
1218 *cc_valid_p = CC_NO_CARRY;
1219 return SHIFT_SPECIAL;
1220 }
1221 if (shift_type == SHIFT_ASHIFT)
1222 {
1223 *assembler_p = "ror\t%0\n\tmov 0,%0\n\tror %0\n";
1224 *cc_valid_p = CC_NO_CARRY;
1225 return SHIFT_SPECIAL;
1226 }
1227 }
1228 break;
1229
1230 default:
1231 abort ();
1232 }
1233
1234 return alg;
1235}
1236
1237/* Emit the assembler code for doing shifts. */
1238
ac42d1e9 1239const char *
a1c8363d 1240emit_a_shift (insn, operands)
ac42d1e9 1241 rtx insn ATTRIBUTE_UNUSED;
a1c8363d
JL
1242 rtx *operands;
1243{
1244 static int loopend_lab;
ac42d1e9 1245 const char *assembler;
a1c8363d 1246 int cc_valid;
a1c8363d
JL
1247 rtx shift = operands[3];
1248 enum machine_mode mode = GET_MODE (shift);
1249 enum rtx_code code = GET_CODE (shift);
1250 enum shift_type shift_type;
1251 enum shift_mode shift_mode;
1252
1253 loopend_lab++;
1254
1255 switch (mode)
1256 {
1257 case HImode:
1258 shift_mode = HIshift;
1259 break;
1260 default:
1261 abort ();
1262 }
1263
1264 switch (code)
1265 {
1266 case ASHIFTRT:
1267 shift_type = SHIFT_ASHIFTRT;
1268 break;
1269 case LSHIFTRT:
1270 shift_type = SHIFT_LSHIFTRT;
1271 break;
1272 case ASHIFT:
1273 shift_type = SHIFT_ASHIFT;
1274 break;
1275 default:
1276 abort ();
1277 }
1278
1279 if (GET_CODE (operands[2]) != CONST_INT)
1280 {
1281 /* Indexing by reg, so have to loop and test at top */
1282 output_asm_insn ("mov %2,%4", operands);
1283 output_asm_insn ("cmp 0,%4", operands);
1284 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
1285
1286 /* Get the assembler code to do one shift. */
1287 get_shift_alg (shift_type, mode, 1, &assembler, &cc_valid);
1288 }
1289 else
1290 {
1291 int n = INTVAL (operands[2]);
1292 enum shift_alg alg;
1293
1294 /* If the count is negative, make it 0. */
1295 if (n < 0)
1296 n = 0;
1297 /* If the count is too big, truncate it.
1298 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
1299 do the intuitive thing. */
1300 else if (n > GET_MODE_BITSIZE (mode))
1301 n = GET_MODE_BITSIZE (mode);
1302
1303 alg = get_shift_alg (shift_type, mode, n, &assembler, &cc_valid);
1304
1305
1306 switch (alg)
1307 {
1308 case SHIFT_INLINE:
1309 /* Emit one bit shifts. */
1310 while (n > 0)
1311 {
1312 output_asm_insn (assembler, operands);
1313 n -= 1;
1314 }
1315
1316 /* Keep track of CC. */
1317 if (cc_valid)
1318 {
1319 cc_status.value1 = operands[0];
1320 cc_status.flags |= cc_valid;
1321 }
1322 return "";
1323
1324 case SHIFT_SPECIAL:
1325 output_asm_insn (assembler, operands);
1326
1327 /* Keep track of CC. */
1328 if (cc_valid)
1329 {
1330 cc_status.value1 = operands[0];
1331 cc_status.flags |= cc_valid;
1332 }
1333 return "";
1334 }
1335
1336 {
1337 fprintf (asm_out_file, "\tmov %d,%s\n", n,
1338 reg_names[REGNO (operands[4])]);
1339 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
1340 output_asm_insn (assembler, operands);
1341 output_asm_insn ("add -1,%4", operands);
1342 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
1343 return "";
1344 }
1345 }
1346
1347 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
1348 output_asm_insn (assembler, operands);
1349 output_asm_insn ("add -1,%4", operands);
1350 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
1351 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
1352
1353 return "";
1354}
1355
1356/* Return an RTX to represent where a value with mode MODE will be returned
1357 from a function. If the result is 0, the argument is pushed. */
1358
1359rtx
1360function_arg (cum, mode, type, named)
1361 CUMULATIVE_ARGS *cum;
1362 enum machine_mode mode;
1363 tree type;
1364 int named;
1365{
1366 rtx result = 0;
1367 int size, align;
1368
1369 /* We only support using 2 data registers as argument registers. */
1370 int nregs = 2;
1371
1372 /* Only pass named arguments in registers. */
1373 if (!named)
1374 return NULL_RTX;
1375
1376 /* Figure out the size of the object to be passed. We lie and claim
1377 PSImode values are only two bytes since they fit in a single
1378 register. */
1379 if (mode == BLKmode)
1380 size = int_size_in_bytes (type);
1381 else if (mode == PSImode)
1382 size = 2;
1383 else
1384 size = GET_MODE_SIZE (mode);
1385
1386 /* Figure out the alignment of the object to be passed. */
1387 align = size;
1388
1389 cum->nbytes = (cum->nbytes + 1) & ~1;
1390
1391 /* Don't pass this arg via a register if all the argument registers
1392 are used up. */
1393 if (cum->nbytes + size > nregs * UNITS_PER_WORD)
1394 return 0;
1395
1396 switch (cum->nbytes / UNITS_PER_WORD)
1397 {
1398 case 0:
c5c76735 1399 result = gen_rtx_REG (mode, 0);
a1c8363d
JL
1400 break;
1401 case 1:
c5c76735 1402 result = gen_rtx_REG (mode, 1);
a1c8363d
JL
1403 break;
1404 default:
1405 result = 0;
1406 }
1407
1408 return result;
1409}
1410
1411/* Return the number of registers to use for an argument passed partially
1412 in registers and partially in memory. */
1413
1414int
1415function_arg_partial_nregs (cum, mode, type, named)
1416 CUMULATIVE_ARGS *cum;
1417 enum machine_mode mode;
1418 tree type;
1419 int named;
1420{
1421 int size, align;
1422
1423 /* We only support using 2 data registers as argument registers. */
1424 int nregs = 2;
1425
1426 return 0;
1427 /* Only pass named arguments in registers. */
1428 if (!named)
1429 return 0;
1430
1431 /* Figure out the size of the object to be passed. */
1432 if (mode == BLKmode)
1433 size = int_size_in_bytes (type);
1434 else if (mode == PSImode)
1435 size = 2;
1436 else
1437 size = GET_MODE_SIZE (mode);
1438
1439 /* Figure out the alignment of the object to be passed. */
1440 align = size;
1441
1442 cum->nbytes = (cum->nbytes + 1) & ~1;
1443
1444 /* Don't pass this arg via a register if all the argument registers
1445 are used up. */
1446 if (cum->nbytes > nregs * UNITS_PER_WORD)
1447 return 0;
1448
1449 if (cum->nbytes + size <= nregs * UNITS_PER_WORD)
1450 return 0;
1451
1452 /* Don't pass this arg via a register if it would be split between
1453 registers and memory. */
1454 if (type == NULL_TREE
1455 && cum->nbytes + size > nregs * UNITS_PER_WORD)
1456 return 0;
1457
1458 return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
1459}
1460
8bb793f3
RH
1461rtx
1462mn10200_va_arg (valist, type)
1463 tree valist, type;
1464{
1465 HOST_WIDE_INT align, rsize;
1466 tree t, ptr, pptr;
1467
1468 /* Compute the rounded size of the type. */
1469 align = PARM_BOUNDARY / BITS_PER_UNIT;
1470 rsize = (((int_size_in_bytes (type) + align - 1) / align) * align);
1471
1472 t = build (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist,
1473 build_int_2 ((rsize > 8 ? 4 : rsize), 0));
1474 TREE_SIDE_EFFECTS (t) = 1;
1475
1476 ptr = build_pointer_type (type);
1477
1478 /* "Large" types are passed by reference. */
1479 if (rsize > 8)
1480 {
1481 pptr = build_pointer_type (ptr);
1482 t = build1 (NOP_EXPR, pptr, t);
1483 TREE_SIDE_EFFECTS (t) = 1;
1484
1485 t = build1 (INDIRECT_REF, ptr, t);
1486 TREE_SIDE_EFFECTS (t) = 1;
1487 }
1488 else
1489 {
1490 t = build1 (NOP_EXPR, ptr, t);
1491 TREE_SIDE_EFFECTS (t) = 1;
1492 }
1493
1494 /* Calculate! */
60860055 1495 return force_reg (Pmode, expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL));
8bb793f3
RH
1496}
1497
ac42d1e9 1498const char *
a1c8363d
JL
1499output_tst (operand, insn)
1500 rtx operand, insn;
1501{
1502
1503 rtx temp;
1504 int past_call = 0;
1505
1506 /* Only tst insns using address registers can be optimized. */
1507 if (REGNO_REG_CLASS (REGNO (operand)) != ADDRESS_REGS)
1508 return "cmp 0,%0";
1509
1510 /* If testing an address register against zero, we can do better if
1511 we know there's a register already holding the value zero. First
1512 see if a global register has been set to zero, else we do a search
1513 for a register holding zero, if both of those fail, then we use a
1514 compare against zero. */
1515 if (zero_dreg || zero_areg)
1516 {
1517 rtx xoperands[2];
1518 xoperands[0] = operand;
1519 xoperands[1] = zero_dreg ? zero_dreg : zero_areg;
1520
1521 output_asm_insn ("cmp %1,%0", xoperands);
1522 return "";
1523 }
1524
1525 /* We can save a byte if we can find a register which has the value
1526 zero in it. */
1527 temp = PREV_INSN (insn);
1528 while (temp)
1529 {
1530 rtx set;
1531
1532 /* We allow the search to go through call insns. We record
1533 the fact that we've past a CALL_INSN and reject matches which
1534 use call clobbered registers. */
1535 if (GET_CODE (temp) == CODE_LABEL
1536 || GET_CODE (temp) == JUMP_INSN
1537 || GET_CODE (temp) == BARRIER)
1538 break;
1539
1540 if (GET_CODE (temp) == CALL_INSN)
1541 past_call = 1;
1542
1543 if (GET_CODE (temp) == NOTE)
1544 {
1545 temp = PREV_INSN (temp);
1546 continue;
1547 }
1548
1549 /* It must be an insn, see if it is a simple set. */
1550 set = single_set (temp);
1551 if (!set)
1552 {
1553 temp = PREV_INSN (temp);
1554 continue;
1555 }
1556
1557 /* Are we setting a register to zero?
1558
1559 If it's a call clobbered register, have we past a call? */
1560 if (REG_P (SET_DEST (set))
1561 && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set)))
1562 && !reg_set_between_p (SET_DEST (set), temp, insn)
1563 && (!past_call
1564 || !call_used_regs[REGNO (SET_DEST (set))]))
1565 {
1566 rtx xoperands[2];
1567 xoperands[0] = operand;
1568 xoperands[1] = SET_DEST (set);
1569
1570 output_asm_insn ("cmp %1,%0", xoperands);
1571 return "";
1572 }
1573 temp = PREV_INSN (temp);
1574 }
1575 return "cmp 0,%0";
1576}
1577
1578/* Return nonzero if OP is a valid operand for a {zero,sign}_extendpsisi
1579 instruction.
1580
1581 It accepts anything that is a general operand or the sum of the
1582 stack pointer and a general operand. */
ac42d1e9 1583int
a1c8363d
JL
1584extendpsi_operand (op, mode)
1585 rtx op;
1586 enum machine_mode mode;
1587{
1588 return (general_operand (op, mode)
1589 || (GET_CODE (op) == PLUS
1590 && XEXP (op, 0) == stack_pointer_rtx
1591 && general_operand (XEXP (op, 1), VOIDmode)));
1592}