Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/stormy16/stormy16.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Xstormy16 target functions. | 1 /* Xstormy16 target functions. |
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, | 2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |
3 2006, 2007, 2008, 2009 Free Software Foundation, Inc. | 3 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. |
4 Contributed by Red Hat, Inc. | 4 Contributed by Red Hat, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify | 8 GCC is free software; you can redistribute it and/or modify |
31 #include "insn-flags.h" | 31 #include "insn-flags.h" |
32 #include "output.h" | 32 #include "output.h" |
33 #include "insn-attr.h" | 33 #include "insn-attr.h" |
34 #include "flags.h" | 34 #include "flags.h" |
35 #include "recog.h" | 35 #include "recog.h" |
36 #include "toplev.h" | 36 #include "diagnostic-core.h" |
37 #include "obstack.h" | 37 #include "obstack.h" |
38 #include "tree.h" | 38 #include "tree.h" |
39 #include "expr.h" | 39 #include "expr.h" |
40 #include "optabs.h" | 40 #include "optabs.h" |
41 #include "except.h" | 41 #include "except.h" |
44 #include "target-def.h" | 44 #include "target-def.h" |
45 #include "tm_p.h" | 45 #include "tm_p.h" |
46 #include "langhooks.h" | 46 #include "langhooks.h" |
47 #include "gimple.h" | 47 #include "gimple.h" |
48 #include "df.h" | 48 #include "df.h" |
49 #include "reload.h" | |
49 #include "ggc.h" | 50 #include "ggc.h" |
50 | 51 |
51 static rtx emit_addhi3_postreload (rtx, rtx, rtx); | 52 static rtx emit_addhi3_postreload (rtx, rtx, rtx); |
52 static void xstormy16_asm_out_constructor (rtx, int); | 53 static void xstormy16_asm_out_constructor (rtx, int); |
53 static void xstormy16_asm_out_destructor (rtx, int); | 54 static void xstormy16_asm_out_destructor (rtx, int); |
101 } | 102 } |
102 | 103 |
103 static int | 104 static int |
104 xstormy16_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED) | 105 xstormy16_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED) |
105 { | 106 { |
106 return (GET_CODE (x) == CONST_INT ? 2 | 107 return (CONST_INT_P (x) ? 2 |
107 : GET_CODE (x) == PLUS ? 7 | 108 : GET_CODE (x) == PLUS ? 7 |
108 : 5); | 109 : 5); |
110 } | |
111 | |
112 /* Worker function for TARGET_MEMORY_MOVE_COST. */ | |
113 | |
114 static int | |
115 xstormy16_memory_move_cost (enum machine_mode mode, reg_class_t rclass, | |
116 bool in) | |
117 { | |
118 return (5 + memory_move_secondary_cost (mode, rclass, in)); | |
109 } | 119 } |
110 | 120 |
111 /* Branches are handled as follows: | 121 /* Branches are handled as follows: |
112 | 122 |
113 1. HImode compare-and-branches. The machine supports these | 123 1. HImode compare-and-branches. The machine supports these |
289 return string; | 299 return string; |
290 } | 300 } |
291 | 301 |
292 code = GET_CODE (op); | 302 code = GET_CODE (op); |
293 | 303 |
294 if (GET_CODE (XEXP (op, 0)) != REG) | 304 if (! REG_P (XEXP (op, 0))) |
295 { | 305 { |
296 code = swap_condition (code); | 306 code = swap_condition (code); |
297 operands = "%3,%2"; | 307 operands = "%3,%2"; |
298 } | 308 } |
299 else | 309 else |
374 { | 384 { |
375 case EQ: case NE: | 385 case EQ: case NE: |
376 { | 386 { |
377 int regnum; | 387 int regnum; |
378 | 388 |
379 gcc_assert (GET_CODE (XEXP (op, 0)) == REG); | 389 gcc_assert (REG_P (XEXP (op, 0))); |
380 | 390 |
381 regnum = REGNO (XEXP (op, 0)); | 391 regnum = REGNO (XEXP (op, 0)); |
382 sprintf (prevop, "or %s,%s", reg_names[regnum], reg_names[regnum+1]); | 392 sprintf (prevop, "or %s,%s", reg_names[regnum], reg_names[regnum+1]); |
383 } | 393 } |
384 break; | 394 break; |
452 copy and the `movM' pattern should use memory as an intermediate storage. | 462 copy and the `movM' pattern should use memory as an intermediate storage. |
453 This case often occurs between floating-point and general registers. */ | 463 This case often occurs between floating-point and general registers. */ |
454 | 464 |
455 enum reg_class | 465 enum reg_class |
456 xstormy16_secondary_reload_class (enum reg_class rclass, | 466 xstormy16_secondary_reload_class (enum reg_class rclass, |
457 enum machine_mode mode, | 467 enum machine_mode mode ATTRIBUTE_UNUSED, |
458 rtx x) | 468 rtx x) |
459 { | 469 { |
460 /* This chip has the interesting property that only the first eight | 470 /* This chip has the interesting property that only the first eight |
461 registers can be moved to/from memory. */ | 471 registers can be moved to/from memory. */ |
462 if ((GET_CODE (x) == MEM | 472 if ((MEM_P (x) |
463 || ((GET_CODE (x) == SUBREG || GET_CODE (x) == REG) | 473 || ((GET_CODE (x) == SUBREG || REG_P (x)) |
464 && (true_regnum (x) == -1 | 474 && (true_regnum (x) == -1 |
465 || true_regnum (x) >= FIRST_PSEUDO_REGISTER))) | 475 || true_regnum (x) >= FIRST_PSEUDO_REGISTER))) |
466 && ! reg_class_subset_p (rclass, EIGHT_REGS)) | 476 && ! reg_class_subset_p (rclass, EIGHT_REGS)) |
467 return EIGHT_REGS; | 477 return EIGHT_REGS; |
468 | 478 |
469 return NO_REGS; | 479 return NO_REGS; |
470 } | 480 } |
471 | 481 |
472 enum reg_class | 482 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS |
473 xstormy16_preferred_reload_class (rtx x, enum reg_class rclass) | 483 and TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */ |
474 { | 484 |
475 if (rclass == GENERAL_REGS | 485 static reg_class_t |
476 && GET_CODE (x) == MEM) | 486 xstormy16_preferred_reload_class (rtx x, reg_class_t rclass) |
487 { | |
488 if (rclass == GENERAL_REGS && MEM_P (x)) | |
477 return EIGHT_REGS; | 489 return EIGHT_REGS; |
478 | 490 |
479 return rclass; | 491 return rclass; |
480 } | 492 } |
481 | 493 |
486 xstormy16_below100_symbol (rtx x, | 498 xstormy16_below100_symbol (rtx x, |
487 enum machine_mode mode ATTRIBUTE_UNUSED) | 499 enum machine_mode mode ATTRIBUTE_UNUSED) |
488 { | 500 { |
489 if (GET_CODE (x) == CONST) | 501 if (GET_CODE (x) == CONST) |
490 x = XEXP (x, 0); | 502 x = XEXP (x, 0); |
491 if (GET_CODE (x) == PLUS | 503 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))) |
492 && GET_CODE (XEXP (x, 1)) == CONST_INT) | |
493 x = XEXP (x, 0); | 504 x = XEXP (x, 0); |
494 | 505 |
495 if (GET_CODE (x) == SYMBOL_REF) | 506 if (GET_CODE (x) == SYMBOL_REF) |
496 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_XSTORMY16_BELOW100) != 0; | 507 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_XSTORMY16_BELOW100) != 0; |
497 | 508 |
498 if (GET_CODE (x) == CONST_INT) | 509 if (CONST_INT_P (x)) |
499 { | 510 { |
500 HOST_WIDE_INT i = INTVAL (x); | 511 HOST_WIDE_INT i = INTVAL (x); |
512 | |
501 if ((i >= 0x0000 && i <= 0x00ff) | 513 if ((i >= 0x0000 && i <= 0x00ff) |
502 || (i >= 0x7f00 && i <= 0x7fff)) | 514 || (i >= 0x7f00 && i <= 0x7fff)) |
503 return 1; | 515 return 1; |
504 } | 516 } |
505 return 0; | 517 return 0; |
509 MEM will get split into smaller sized accesses. */ | 521 MEM will get split into smaller sized accesses. */ |
510 | 522 |
511 int | 523 int |
512 xstormy16_splittable_below100_operand (rtx x, enum machine_mode mode) | 524 xstormy16_splittable_below100_operand (rtx x, enum machine_mode mode) |
513 { | 525 { |
514 if (GET_CODE (x) == MEM && MEM_VOLATILE_P (x)) | 526 if (MEM_P (x) && MEM_VOLATILE_P (x)) |
515 return 0; | 527 return 0; |
516 return xstormy16_below100_operand (x, mode); | 528 return xstormy16_below100_operand (x, mode); |
517 } | 529 } |
518 | 530 |
519 /* Expand an 8-bit IOR. This either detects the one case we can | 531 /* Expand an 8-bit IOR. This either detects the one case we can |
538 if (out != operands[0]) | 550 if (out != operands[0]) |
539 emit_move_insn (operands[0], out); | 551 emit_move_insn (operands[0], out); |
540 return; | 552 return; |
541 } | 553 } |
542 | 554 |
543 if (GET_CODE (in) != REG) | 555 if (! REG_P (in)) |
544 in = copy_to_mode_reg (QImode, in); | 556 in = copy_to_mode_reg (QImode, in); |
545 if (GET_CODE (val) != REG | 557 |
546 && GET_CODE (val) != CONST_INT) | 558 if (! REG_P (val) && ! CONST_INT_P (val)) |
547 val = copy_to_mode_reg (QImode, val); | 559 val = copy_to_mode_reg (QImode, val); |
548 if (GET_CODE (out) != REG) | 560 |
561 if (! REG_P (out)) | |
549 out = gen_reg_rtx (QImode); | 562 out = gen_reg_rtx (QImode); |
550 | 563 |
551 in = simplify_gen_subreg (HImode, in, QImode, 0); | 564 in = simplify_gen_subreg (HImode, in, QImode, 0); |
552 outsub = simplify_gen_subreg (HImode, out, QImode, 0); | 565 outsub = simplify_gen_subreg (HImode, out, QImode, 0); |
553 if (GET_CODE (val) != CONST_INT) | 566 |
567 if (! CONST_INT_P (val)) | |
554 val = simplify_gen_subreg (HImode, val, QImode, 0); | 568 val = simplify_gen_subreg (HImode, val, QImode, 0); |
555 | 569 |
556 emit_insn (gen_iorhi3 (outsub, in, val)); | 570 emit_insn (gen_iorhi3 (outsub, in, val)); |
557 | 571 |
558 if (out != operands[0]) | 572 if (out != operands[0]) |
581 if (out != operands[0]) | 595 if (out != operands[0]) |
582 emit_move_insn (operands[0], out); | 596 emit_move_insn (operands[0], out); |
583 return; | 597 return; |
584 } | 598 } |
585 | 599 |
586 if (GET_CODE (in) != REG) | 600 if (! REG_P (in)) |
587 in = copy_to_mode_reg (QImode, in); | 601 in = copy_to_mode_reg (QImode, in); |
588 if (GET_CODE (val) != REG | 602 |
589 && GET_CODE (val) != CONST_INT) | 603 if (! REG_P (val) && ! CONST_INT_P (val)) |
590 val = copy_to_mode_reg (QImode, val); | 604 val = copy_to_mode_reg (QImode, val); |
591 if (GET_CODE (out) != REG) | 605 |
606 if (! REG_P (out)) | |
592 out = gen_reg_rtx (QImode); | 607 out = gen_reg_rtx (QImode); |
593 | 608 |
594 in = simplify_gen_subreg (HImode, in, QImode, 0); | 609 in = simplify_gen_subreg (HImode, in, QImode, 0); |
595 outsub = simplify_gen_subreg (HImode, out, QImode, 0); | 610 outsub = simplify_gen_subreg (HImode, out, QImode, 0); |
596 if (GET_CODE (val) != CONST_INT) | 611 |
612 if (! CONST_INT_P (val)) | |
597 val = simplify_gen_subreg (HImode, val, QImode, 0); | 613 val = simplify_gen_subreg (HImode, val, QImode, 0); |
598 | 614 |
599 emit_insn (gen_andhi3 (outsub, in, val)); | 615 emit_insn (gen_andhi3 (outsub, in, val)); |
600 | 616 |
601 if (out != operands[0]) | 617 if (out != operands[0]) |
602 emit_move_insn (operands[0], out); | 618 emit_move_insn (operands[0], out); |
603 } | 619 } |
604 | 620 |
605 #define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET) \ | 621 #define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET) \ |
606 (GET_CODE (X) == CONST_INT \ | 622 (CONST_INT_P (X) \ |
607 && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 2048) < 4096) | 623 && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 2048) < 4096) |
608 | 624 |
609 #define LEGITIMATE_ADDRESS_CONST_INT_P(X, OFFSET) \ | 625 #define LEGITIMATE_ADDRESS_CONST_INT_P(X, OFFSET) \ |
610 (GET_CODE (X) == CONST_INT \ | 626 (CONST_INT_P (X) \ |
611 && INTVAL (X) + (OFFSET) >= 0 \ | 627 && INTVAL (X) + (OFFSET) >= 0 \ |
612 && INTVAL (X) + (OFFSET) < 0x8000 \ | 628 && INTVAL (X) + (OFFSET) < 0x8000 \ |
613 && (INTVAL (X) + (OFFSET) < 0x100 || INTVAL (X) + (OFFSET) >= 0x7F00)) | 629 && (INTVAL (X) + (OFFSET) < 0x100 || INTVAL (X) + (OFFSET) >= 0x7F00)) |
614 | 630 |
615 static bool | 631 bool |
616 xstormy16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, | 632 xstormy16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, |
617 rtx x, bool strict) | 633 rtx x, bool strict) |
618 { | 634 { |
619 if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0)) | 635 if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0)) |
620 return 1; | 636 return true; |
621 | 637 |
622 if (GET_CODE (x) == PLUS | 638 if (GET_CODE (x) == PLUS |
623 && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 0)) | 639 && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 0)) |
624 { | 640 { |
625 x = XEXP (x, 0); | 641 x = XEXP (x, 0); |
626 /* PR 31232: Do not allow INT+INT as an address. */ | 642 /* PR 31232: Do not allow INT+INT as an address. */ |
627 if (GET_CODE (x) == CONST_INT) | 643 if (CONST_INT_P (x)) |
628 return 0; | 644 return false; |
629 } | 645 } |
630 | 646 |
631 if ((GET_CODE (x) == PRE_MODIFY | 647 if ((GET_CODE (x) == PRE_MODIFY && CONST_INT_P (XEXP (XEXP (x, 1), 1))) |
632 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT) | |
633 || GET_CODE (x) == POST_INC | 648 || GET_CODE (x) == POST_INC |
634 || GET_CODE (x) == PRE_DEC) | 649 || GET_CODE (x) == PRE_DEC) |
635 x = XEXP (x, 0); | 650 x = XEXP (x, 0); |
636 | 651 |
637 if (GET_CODE (x) == REG && REGNO_OK_FOR_BASE_P (REGNO (x)) | 652 if (REG_P (x) |
653 && REGNO_OK_FOR_BASE_P (REGNO (x)) | |
638 && (! strict || REGNO (x) < FIRST_PSEUDO_REGISTER)) | 654 && (! strict || REGNO (x) < FIRST_PSEUDO_REGISTER)) |
639 return 1; | 655 return true; |
640 | 656 |
641 if (xstormy16_below100_symbol (x, mode)) | 657 if (xstormy16_below100_symbol (x, mode)) |
642 return 1; | 658 return true; |
643 | 659 |
644 return 0; | 660 return false; |
645 } | 661 } |
646 | 662 |
647 /* Return nonzero if memory address X (an RTX) can have different | 663 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P. |
648 meanings depending on the machine mode of the memory reference it | |
649 is used for or if the address is valid for some modes but not | |
650 others. | |
651 | |
652 Autoincrement and autodecrement addresses typically have mode-dependent | |
653 effects because the amount of the increment or decrement is the size of the | |
654 operand being addressed. Some machines have other mode-dependent addresses. | |
655 Many RISC machines have no mode-dependent addresses. | |
656 | |
657 You may assume that ADDR is a valid address for the machine. | |
658 | 664 |
659 On this chip, this is true if the address is valid with an offset | 665 On this chip, this is true if the address is valid with an offset |
660 of 0 but not of 6, because in that case it cannot be used as an | 666 of 0 but not of 6, because in that case it cannot be used as an |
661 address for DImode or DFmode, or if the address is a post-increment | 667 address for DImode or DFmode, or if the address is a post-increment |
662 or pre-decrement address. */ | 668 or pre-decrement address. */ |
663 | 669 |
664 int | 670 static bool |
665 xstormy16_mode_dependent_address_p (rtx x) | 671 xstormy16_mode_dependent_address_p (const_rtx x) |
666 { | 672 { |
667 if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0) | 673 if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0) |
668 && ! LEGITIMATE_ADDRESS_CONST_INT_P (x, 6)) | 674 && ! LEGITIMATE_ADDRESS_CONST_INT_P (x, 6)) |
669 return 1; | 675 return true; |
670 | 676 |
671 if (GET_CODE (x) == PLUS | 677 if (GET_CODE (x) == PLUS |
672 && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 0) | 678 && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 0) |
673 && ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 6)) | 679 && ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 6)) |
674 return 1; | 680 return true; |
675 | |
676 if (GET_CODE (x) == PLUS) | |
677 x = XEXP (x, 0); | |
678 | 681 |
679 /* Auto-increment addresses are now treated generically in recog.c. */ | 682 /* Auto-increment addresses are now treated generically in recog.c. */ |
680 return 0; | 683 return false; |
681 } | |
682 | |
683 /* A C expression that defines the optional machine-dependent constraint | |
684 letters (`Q', `R', `S', `T', `U') that can be used to segregate specific | |
685 types of operands, usually memory references, for the target machine. | |
686 Normally this macro will not be defined. If it is required for a particular | |
687 target machine, it should return 1 if VALUE corresponds to the operand type | |
688 represented by the constraint letter C. If C is not defined as an extra | |
689 constraint, the value returned should be 0 regardless of VALUE. */ | |
690 | |
691 int | |
692 xstormy16_extra_constraint_p (rtx x, int c) | |
693 { | |
694 switch (c) | |
695 { | |
696 /* 'Q' is for pushes. */ | |
697 case 'Q': | |
698 return (GET_CODE (x) == MEM | |
699 && GET_CODE (XEXP (x, 0)) == POST_INC | |
700 && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx); | |
701 | |
702 /* 'R' is for pops. */ | |
703 case 'R': | |
704 return (GET_CODE (x) == MEM | |
705 && GET_CODE (XEXP (x, 0)) == PRE_DEC | |
706 && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx); | |
707 | |
708 /* 'S' is for immediate memory addresses. */ | |
709 case 'S': | |
710 return (GET_CODE (x) == MEM | |
711 && GET_CODE (XEXP (x, 0)) == CONST_INT | |
712 && xstormy16_legitimate_address_p (VOIDmode, XEXP (x, 0), 0)); | |
713 | |
714 /* 'T' is for Rx. */ | |
715 case 'T': | |
716 /* Not implemented yet. */ | |
717 return 0; | |
718 | |
719 /* 'U' is for CONST_INT values not between 2 and 15 inclusive, | |
720 for allocating a scratch register for 32-bit shifts. */ | |
721 case 'U': | |
722 return (GET_CODE (x) == CONST_INT | |
723 && (INTVAL (x) < 2 || INTVAL (x) > 15)); | |
724 | |
725 /* 'Z' is for CONST_INT value zero. This is for adding zero to | |
726 a register in addhi3, which would otherwise require a carry. */ | |
727 case 'Z': | |
728 return (GET_CODE (x) == CONST_INT | |
729 && (INTVAL (x) == 0)); | |
730 | |
731 case 'W': | |
732 return xstormy16_below100_operand (x, GET_MODE (x)); | |
733 | |
734 default: | |
735 return 0; | |
736 } | |
737 } | 684 } |
738 | 685 |
739 int | 686 int |
740 short_memory_operand (rtx x, enum machine_mode mode) | 687 short_memory_operand (rtx x, enum machine_mode mode) |
741 { | 688 { |
767 && mode != QImode && mode != HImode | 714 && mode != QImode && mode != HImode |
768 && nonimmediate_operand (dest, mode) | 715 && nonimmediate_operand (dest, mode) |
769 && general_operand (src, mode)); | 716 && general_operand (src, mode)); |
770 | 717 |
771 /* This case is not supported below, and shouldn't be generated. */ | 718 /* This case is not supported below, and shouldn't be generated. */ |
772 gcc_assert (GET_CODE (dest) != MEM || GET_CODE (src) != MEM); | 719 gcc_assert (! MEM_P (dest) || ! MEM_P (src)); |
773 | 720 |
774 /* This case is very very bad after reload, so trap it now. */ | 721 /* This case is very very bad after reload, so trap it now. */ |
775 gcc_assert (GET_CODE (dest) != SUBREG && GET_CODE (src) != SUBREG); | 722 gcc_assert (GET_CODE (dest) != SUBREG && GET_CODE (src) != SUBREG); |
776 | 723 |
777 /* The general idea is to copy by words, offsetting the source and | 724 /* The general idea is to copy by words, offsetting the source and |
782 | 729 |
783 It's also possible that the copy overlaps so that the direction | 730 It's also possible that the copy overlaps so that the direction |
784 must be reversed. */ | 731 must be reversed. */ |
785 direction = 1; | 732 direction = 1; |
786 | 733 |
787 if (GET_CODE (dest) == MEM) | 734 if (MEM_P (dest)) |
788 { | 735 { |
789 mem_operand = XEXP (dest, 0); | 736 mem_operand = XEXP (dest, 0); |
790 dest_modifies = side_effects_p (mem_operand); | 737 dest_modifies = side_effects_p (mem_operand); |
791 if (auto_inc_p (mem_operand)) | 738 if (auto_inc_p (mem_operand)) |
792 auto_inc_reg_rtx = XEXP (mem_operand, 0); | 739 auto_inc_reg_rtx = XEXP (mem_operand, 0); |
795 { | 742 { |
796 dest = copy_rtx (dest); | 743 dest = copy_rtx (dest); |
797 MEM_VOLATILE_P (dest) = 0; | 744 MEM_VOLATILE_P (dest) = 0; |
798 } | 745 } |
799 } | 746 } |
800 else if (GET_CODE (src) == MEM) | 747 else if (MEM_P (src)) |
801 { | 748 { |
802 mem_operand = XEXP (src, 0); | 749 mem_operand = XEXP (src, 0); |
803 src_modifies = side_effects_p (mem_operand); | 750 src_modifies = side_effects_p (mem_operand); |
804 if (auto_inc_p (mem_operand)) | 751 if (auto_inc_p (mem_operand)) |
805 auto_inc_reg_rtx = XEXP (mem_operand, 0); | 752 auto_inc_reg_rtx = XEXP (mem_operand, 0); |
813 else | 760 else |
814 mem_operand = NULL_RTX; | 761 mem_operand = NULL_RTX; |
815 | 762 |
816 if (mem_operand == NULL_RTX) | 763 if (mem_operand == NULL_RTX) |
817 { | 764 { |
818 if (GET_CODE (src) == REG | 765 if (REG_P (src) |
819 && GET_CODE (dest) == REG | 766 && REG_P (dest) |
820 && reg_overlap_mentioned_p (dest, src) | 767 && reg_overlap_mentioned_p (dest, src) |
821 && REGNO (dest) > REGNO (src)) | 768 && REGNO (dest) > REGNO (src)) |
822 direction = -1; | 769 direction = -1; |
823 } | 770 } |
824 else if (GET_CODE (mem_operand) == PRE_DEC | 771 else if (GET_CODE (mem_operand) == PRE_DEC |
825 || (GET_CODE (mem_operand) == PLUS | 772 || (GET_CODE (mem_operand) == PLUS |
826 && GET_CODE (XEXP (mem_operand, 0)) == PRE_DEC)) | 773 && GET_CODE (XEXP (mem_operand, 0)) == PRE_DEC)) |
827 direction = -1; | 774 direction = -1; |
828 else if (GET_CODE (src) == MEM | 775 else if (MEM_P (src) && reg_overlap_mentioned_p (dest, src)) |
829 && reg_overlap_mentioned_p (dest, src)) | |
830 { | 776 { |
831 int regno; | 777 int regno; |
832 | 778 |
833 gcc_assert (GET_CODE (dest) == REG); | 779 gcc_assert (REG_P (dest)); |
834 regno = REGNO (dest); | 780 regno = REGNO (dest); |
835 | 781 |
836 gcc_assert (refers_to_regno_p (regno, regno + num_words, | 782 gcc_assert (refers_to_regno_p (regno, regno + num_words, |
837 mem_operand, 0)); | 783 mem_operand, 0)); |
838 | 784 |
884 mode MODE from SRC to DEST. */ | 830 mode MODE from SRC to DEST. */ |
885 | 831 |
886 void | 832 void |
887 xstormy16_expand_move (enum machine_mode mode, rtx dest, rtx src) | 833 xstormy16_expand_move (enum machine_mode mode, rtx dest, rtx src) |
888 { | 834 { |
889 if ((GET_CODE (dest) == MEM) && (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY)) | 835 if (MEM_P (dest) && (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY)) |
890 { | 836 { |
891 rtx pmv = XEXP (dest, 0); | 837 rtx pmv = XEXP (dest, 0); |
892 rtx dest_reg = XEXP (pmv, 0); | 838 rtx dest_reg = XEXP (pmv, 0); |
893 rtx dest_mod = XEXP (pmv, 1); | 839 rtx dest_mod = XEXP (pmv, 1); |
894 rtx set = gen_rtx_SET (Pmode, dest_reg, dest_mod); | 840 rtx set = gen_rtx_SET (Pmode, dest_reg, dest_mod); |
895 rtx clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (BImode, CARRY_REGNUM)); | 841 rtx clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (BImode, CARRY_REGNUM)); |
896 | 842 |
897 dest = gen_rtx_MEM (mode, dest_reg); | 843 dest = gen_rtx_MEM (mode, dest_reg); |
898 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber))); | 844 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber))); |
899 } | 845 } |
900 else if ((GET_CODE (src) == MEM) && (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)) | 846 else if (MEM_P (src) && (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)) |
901 { | 847 { |
902 rtx pmv = XEXP (src, 0); | 848 rtx pmv = XEXP (src, 0); |
903 rtx src_reg = XEXP (pmv, 0); | 849 rtx src_reg = XEXP (pmv, 0); |
904 rtx src_mod = XEXP (pmv, 1); | 850 rtx src_mod = XEXP (pmv, 1); |
905 rtx set = gen_rtx_SET (Pmode, src_reg, src_mod); | 851 rtx set = gen_rtx_SET (Pmode, src_reg, src_mod); |
910 } | 856 } |
911 | 857 |
912 /* There are only limited immediate-to-memory move instructions. */ | 858 /* There are only limited immediate-to-memory move instructions. */ |
913 if (! reload_in_progress | 859 if (! reload_in_progress |
914 && ! reload_completed | 860 && ! reload_completed |
915 && GET_CODE (dest) == MEM | 861 && MEM_P (dest) |
916 && (GET_CODE (XEXP (dest, 0)) != CONST_INT | 862 && (! CONST_INT_P (XEXP (dest, 0)) |
917 || ! xstormy16_legitimate_address_p (mode, XEXP (dest, 0), 0)) | 863 || ! xstormy16_legitimate_address_p (mode, XEXP (dest, 0), 0)) |
918 && ! xstormy16_below100_operand (dest, mode) | 864 && ! xstormy16_below100_operand (dest, mode) |
919 && GET_CODE (src) != REG | 865 && ! REG_P (src) |
920 && GET_CODE (src) != SUBREG) | 866 && GET_CODE (src) != SUBREG) |
921 src = copy_to_mode_reg (mode, src); | 867 src = copy_to_mode_reg (mode, src); |
922 | 868 |
923 /* Don't emit something we would immediately split. */ | 869 /* Don't emit something we would immediately split. */ |
924 if (reload_completed | 870 if (reload_completed |
1106 gen_rtx_MEM (Pmode, stack_pointer_rtx), | 1052 gen_rtx_MEM (Pmode, stack_pointer_rtx), |
1107 reg); | 1053 reg); |
1108 XVECEXP (dwarf, 0, 1) = gen_rtx_SET (Pmode, stack_pointer_rtx, | 1054 XVECEXP (dwarf, 0, 1) = gen_rtx_SET (Pmode, stack_pointer_rtx, |
1109 plus_constant (stack_pointer_rtx, | 1055 plus_constant (stack_pointer_rtx, |
1110 GET_MODE_SIZE (Pmode))); | 1056 GET_MODE_SIZE (Pmode))); |
1111 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, | 1057 add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); |
1112 dwarf, | |
1113 REG_NOTES (insn)); | |
1114 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 0)) = 1; | 1058 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 0)) = 1; |
1115 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 1)) = 1; | 1059 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 1)) = 1; |
1116 } | 1060 } |
1117 | 1061 |
1118 /* Push each of the registers to save. */ | 1062 /* Push each of the registers to save. */ |
1131 gen_rtx_MEM (Pmode, stack_pointer_rtx), | 1075 gen_rtx_MEM (Pmode, stack_pointer_rtx), |
1132 reg); | 1076 reg); |
1133 XVECEXP (dwarf, 0, 1) = gen_rtx_SET (Pmode, stack_pointer_rtx, | 1077 XVECEXP (dwarf, 0, 1) = gen_rtx_SET (Pmode, stack_pointer_rtx, |
1134 plus_constant (stack_pointer_rtx, | 1078 plus_constant (stack_pointer_rtx, |
1135 GET_MODE_SIZE (Pmode))); | 1079 GET_MODE_SIZE (Pmode))); |
1136 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, | 1080 add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); |
1137 dwarf, | |
1138 REG_NOTES (insn)); | |
1139 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 0)) = 1; | 1081 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 0)) = 1; |
1140 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 1)) = 1; | 1082 RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 1)) = 1; |
1141 } | 1083 } |
1142 | 1084 |
1143 /* It's just possible that the SP here might be what we need for | 1085 /* It's just possible that the SP here might be what we need for |
1176 | 1118 |
1177 int | 1119 int |
1178 direct_return (void) | 1120 direct_return (void) |
1179 { | 1121 { |
1180 return (reload_completed | 1122 return (reload_completed |
1181 && xstormy16_compute_stack_layout ().frame_size == 0); | 1123 && xstormy16_compute_stack_layout ().frame_size == 0 |
1124 && ! xstormy16_interrupt_function_p ()); | |
1182 } | 1125 } |
1183 | 1126 |
1184 /* Called after register allocation to add any instructions needed for | 1127 /* Called after register allocation to add any instructions needed for |
1185 the epilogue. Using an epilogue insn is favored compared to putting | 1128 the epilogue. Using an epilogue insn is favored compared to putting |
1186 all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro, | 1129 all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro, |
1191 | 1134 |
1192 void | 1135 void |
1193 xstormy16_expand_epilogue (void) | 1136 xstormy16_expand_epilogue (void) |
1194 { | 1137 { |
1195 struct xstormy16_stack_layout layout; | 1138 struct xstormy16_stack_layout layout; |
1196 rtx mem_pop_rtx, insn; | 1139 rtx mem_pop_rtx; |
1197 int regno; | 1140 int regno; |
1198 const int ifun = xstormy16_interrupt_function_p (); | 1141 const int ifun = xstormy16_interrupt_function_p (); |
1199 | 1142 |
1200 mem_pop_rtx = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx); | 1143 mem_pop_rtx = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx); |
1201 mem_pop_rtx = gen_rtx_MEM (HImode, mem_pop_rtx); | 1144 mem_pop_rtx = gen_rtx_MEM (HImode, mem_pop_rtx); |
1244 xstormy16_function_profiler (void) | 1187 xstormy16_function_profiler (void) |
1245 { | 1188 { |
1246 sorry ("function_profiler support"); | 1189 sorry ("function_profiler support"); |
1247 } | 1190 } |
1248 | 1191 |
1249 /* Return an updated summarizer variable CUM to advance past an | 1192 /* Update CUM to advance past an argument in the argument list. The |
1250 argument in the argument list. The values MODE, TYPE and NAMED | 1193 values MODE, TYPE and NAMED describe that argument. Once this is |
1251 describe that argument. Once this is done, the variable CUM is | 1194 done, the variable CUM is suitable for analyzing the *following* |
1252 suitable for analyzing the *following* argument with | 1195 argument with `TARGET_FUNCTION_ARG', etc. |
1253 `FUNCTION_ARG', etc. | |
1254 | 1196 |
1255 This function need not do anything if the argument in question was | 1197 This function need not do anything if the argument in question was |
1256 passed on the stack. The compiler knows how to track the amount of | 1198 passed on the stack. The compiler knows how to track the amount of |
1257 stack space used for arguments without any special help. However, | 1199 stack space used for arguments without any special help. However, |
1258 it makes life easier for xstormy16_build_va_list if it does update | 1200 it makes life easier for xstormy16_build_va_list if it does update |
1259 the word count. */ | 1201 the word count. */ |
1260 | 1202 |
1261 CUMULATIVE_ARGS | 1203 static void |
1262 xstormy16_function_arg_advance (CUMULATIVE_ARGS cum, enum machine_mode mode, | 1204 xstormy16_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, |
1263 tree type, int named ATTRIBUTE_UNUSED) | 1205 const_tree type, bool named ATTRIBUTE_UNUSED) |
1264 { | 1206 { |
1265 /* If an argument would otherwise be passed partially in registers, | 1207 /* If an argument would otherwise be passed partially in registers, |
1266 and partially on the stack, the whole of it is passed on the | 1208 and partially on the stack, the whole of it is passed on the |
1267 stack. */ | 1209 stack. */ |
1268 if (cum < NUM_ARGUMENT_REGISTERS | 1210 if (*cum < NUM_ARGUMENT_REGISTERS |
1269 && cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS) | 1211 && *cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS) |
1270 cum = NUM_ARGUMENT_REGISTERS; | 1212 *cum = NUM_ARGUMENT_REGISTERS; |
1271 | 1213 |
1272 cum += XSTORMY16_WORD_SIZE (type, mode); | 1214 *cum += XSTORMY16_WORD_SIZE (type, mode); |
1273 | 1215 } |
1274 return cum; | 1216 |
1275 } | 1217 static rtx |
1276 | 1218 xstormy16_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, |
1277 rtx | 1219 const_tree type, bool named ATTRIBUTE_UNUSED) |
1278 xstormy16_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, | |
1279 tree type, int named ATTRIBUTE_UNUSED) | |
1280 { | 1220 { |
1281 if (mode == VOIDmode) | 1221 if (mode == VOIDmode) |
1282 return const0_rtx; | 1222 return const0_rtx; |
1283 if (targetm.calls.must_pass_in_stack (mode, type) | 1223 if (targetm.calls.must_pass_in_stack (mode, type) |
1284 || cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS) | 1224 || *cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS) |
1285 return NULL_RTX; | 1225 return NULL_RTX; |
1286 return gen_rtx_REG (mode, cum + 2); | 1226 return gen_rtx_REG (mode, *cum + FIRST_ARGUMENT_REGISTER); |
1287 } | 1227 } |
1288 | 1228 |
1289 /* Build the va_list type. | 1229 /* Build the va_list type. |
1290 | 1230 |
1291 For this chip, va_list is a record containing a counter and a pointer. | 1231 For this chip, va_list is a record containing a counter and a pointer. |
1311 unsigned_type_node); | 1251 unsigned_type_node); |
1312 | 1252 |
1313 DECL_FIELD_CONTEXT (f_1) = record; | 1253 DECL_FIELD_CONTEXT (f_1) = record; |
1314 DECL_FIELD_CONTEXT (f_2) = record; | 1254 DECL_FIELD_CONTEXT (f_2) = record; |
1315 | 1255 |
1316 TREE_CHAIN (record) = type_decl; | 1256 TYPE_STUB_DECL (record) = type_decl; |
1317 TYPE_NAME (record) = type_decl; | 1257 TYPE_NAME (record) = type_decl; |
1318 TYPE_FIELDS (record) = f_1; | 1258 TYPE_FIELDS (record) = f_1; |
1319 TREE_CHAIN (f_1) = f_2; | 1259 DECL_CHAIN (f_1) = f_2; |
1320 | 1260 |
1321 layout_type (record); | 1261 layout_type (record); |
1322 | 1262 |
1323 return record; | 1263 return record; |
1324 } | 1264 } |
1337 | 1277 |
1338 if (xstormy16_interrupt_function_p ()) | 1278 if (xstormy16_interrupt_function_p ()) |
1339 error ("cannot use va_start in interrupt function"); | 1279 error ("cannot use va_start in interrupt function"); |
1340 | 1280 |
1341 f_base = TYPE_FIELDS (va_list_type_node); | 1281 f_base = TYPE_FIELDS (va_list_type_node); |
1342 f_count = TREE_CHAIN (f_base); | 1282 f_count = DECL_CHAIN (f_base); |
1343 | 1283 |
1344 base = build3 (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE); | 1284 base = build3 (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE); |
1345 count = build3 (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count, | 1285 count = build3 (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count, |
1346 NULL_TREE); | 1286 NULL_TREE); |
1347 | 1287 |
1374 tree lab_gotaddr, lab_fromstack; | 1314 tree lab_gotaddr, lab_fromstack; |
1375 int size, size_of_reg_args, must_stack; | 1315 int size, size_of_reg_args, must_stack; |
1376 tree size_tree; | 1316 tree size_tree; |
1377 | 1317 |
1378 f_base = TYPE_FIELDS (va_list_type_node); | 1318 f_base = TYPE_FIELDS (va_list_type_node); |
1379 f_count = TREE_CHAIN (f_base); | 1319 f_count = DECL_CHAIN (f_base); |
1380 | 1320 |
1381 base = build3 (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE); | 1321 base = build3 (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE); |
1382 count = build3 (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count, | 1322 count = build3 (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count, |
1383 NULL_TREE); | 1323 NULL_TREE); |
1384 | 1324 |
1487 | 1427 |
1488 emit_insn (gen_lshrhi3 (reg_fnaddr, reg_fnaddr, GEN_INT (8))); | 1428 emit_insn (gen_lshrhi3 (reg_fnaddr, reg_fnaddr, GEN_INT (8))); |
1489 emit_move_insn (reg_addr_mem, reg_fnaddr); | 1429 emit_move_insn (reg_addr_mem, reg_fnaddr); |
1490 } | 1430 } |
1491 | 1431 |
1492 /* Worker function for FUNCTION_VALUE. */ | 1432 /* Worker function for TARGET_FUNCTION_VALUE. */ |
1493 | 1433 |
1494 rtx | 1434 static rtx |
1495 xstormy16_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED) | 1435 xstormy16_function_value (const_tree valtype, |
1436 const_tree func ATTRIBUTE_UNUSED, | |
1437 bool outgoing ATTRIBUTE_UNUSED) | |
1496 { | 1438 { |
1497 enum machine_mode mode; | 1439 enum machine_mode mode; |
1498 mode = TYPE_MODE (valtype); | 1440 mode = TYPE_MODE (valtype); |
1499 PROMOTE_MODE (mode, 0, valtype); | 1441 PROMOTE_MODE (mode, 0, valtype); |
1500 return gen_rtx_REG (mode, RETURN_VALUE_REGNUM); | 1442 return gen_rtx_REG (mode, RETURN_VALUE_REGNUM); |
1443 } | |
1444 | |
1445 /* Worker function for TARGET_LIBCALL_VALUE. */ | |
1446 | |
1447 static rtx | |
1448 xstormy16_libcall_value (enum machine_mode mode, | |
1449 const_rtx fun ATTRIBUTE_UNUSED) | |
1450 { | |
1451 return gen_rtx_REG (mode, RETURN_VALUE_REGNUM); | |
1452 } | |
1453 | |
1454 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P. */ | |
1455 | |
1456 static bool | |
1457 xstormy16_function_value_regno_p (const unsigned int regno) | |
1458 { | |
1459 return (regno == RETURN_VALUE_REGNUM); | |
1501 } | 1460 } |
1502 | 1461 |
1503 /* A C compound statement that outputs the assembler code for a thunk function, | 1462 /* A C compound statement that outputs the assembler code for a thunk function, |
1504 used to implement C++ virtual function calls with multiple inheritance. The | 1463 used to implement C++ virtual function calls with multiple inheritance. The |
1505 thunk acts as a wrapper around a virtual function, adjusting the implicit | 1464 thunk acts as a wrapper around a virtual function, adjusting the implicit |
1562 { | 1521 { |
1563 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl); | 1522 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl); |
1564 rtx symbol; | 1523 rtx symbol; |
1565 | 1524 |
1566 if (mem != NULL_RTX | 1525 if (mem != NULL_RTX |
1567 && GET_CODE (mem) == MEM | 1526 && MEM_P (mem) |
1568 && GET_CODE (symbol = XEXP (mem, 0)) == SYMBOL_REF | 1527 && GET_CODE (symbol = XEXP (mem, 0)) == SYMBOL_REF |
1569 && SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_XSTORMY16_BELOW100) | 1528 && SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_XSTORMY16_BELOW100) |
1570 { | 1529 { |
1571 const char *name2; | 1530 const char *name2; |
1572 int p2align = 0; | 1531 int p2align = 0; |
1681 switch_to_section (get_section (section, 0, NULL)); | 1640 switch_to_section (get_section (section, 0, NULL)); |
1682 assemble_align (POINTER_SIZE); | 1641 assemble_align (POINTER_SIZE); |
1683 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); | 1642 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); |
1684 } | 1643 } |
1685 | 1644 |
1686 /* Print a memory address as an operand to reference that memory location. */ | 1645 /* Worker function for TARGET_PRINT_OPERAND_ADDRESS. |
1687 | 1646 |
1688 void | 1647 Print a memory address as an operand to reference that memory location. */ |
1648 | |
1649 static void | |
1689 xstormy16_print_operand_address (FILE *file, rtx address) | 1650 xstormy16_print_operand_address (FILE *file, rtx address) |
1690 { | 1651 { |
1691 HOST_WIDE_INT offset; | 1652 HOST_WIDE_INT offset; |
1692 int pre_dec, post_inc; | 1653 int pre_dec, post_inc; |
1693 | 1654 |
1694 /* There are a few easy cases. */ | 1655 /* There are a few easy cases. */ |
1695 if (GET_CODE (address) == CONST_INT) | 1656 if (CONST_INT_P (address)) |
1696 { | 1657 { |
1697 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (address) & 0xFFFF); | 1658 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (address) & 0xFFFF); |
1698 return; | 1659 return; |
1699 } | 1660 } |
1700 | 1661 |
1701 if (CONSTANT_P (address) || GET_CODE (address) == CODE_LABEL) | 1662 if (CONSTANT_P (address) || LABEL_P (address)) |
1702 { | 1663 { |
1703 output_addr_const (file, address); | 1664 output_addr_const (file, address); |
1704 return; | 1665 return; |
1705 } | 1666 } |
1706 | 1667 |
1707 /* Otherwise, it's hopefully something of the form | 1668 /* Otherwise, it's hopefully something of the form |
1708 (plus:HI (pre_dec:HI (reg:HI ...)) (const_int ...)). */ | 1669 (plus:HI (pre_dec:HI (reg:HI ...)) (const_int ...)). */ |
1709 if (GET_CODE (address) == PLUS) | 1670 if (GET_CODE (address) == PLUS) |
1710 { | 1671 { |
1711 gcc_assert (GET_CODE (XEXP (address, 1)) == CONST_INT); | 1672 gcc_assert (CONST_INT_P (XEXP (address, 1))); |
1712 offset = INTVAL (XEXP (address, 1)); | 1673 offset = INTVAL (XEXP (address, 1)); |
1713 address = XEXP (address, 0); | 1674 address = XEXP (address, 0); |
1714 } | 1675 } |
1715 else | 1676 else |
1716 offset = 0; | 1677 offset = 0; |
1718 pre_dec = (GET_CODE (address) == PRE_DEC); | 1679 pre_dec = (GET_CODE (address) == PRE_DEC); |
1719 post_inc = (GET_CODE (address) == POST_INC); | 1680 post_inc = (GET_CODE (address) == POST_INC); |
1720 if (pre_dec || post_inc) | 1681 if (pre_dec || post_inc) |
1721 address = XEXP (address, 0); | 1682 address = XEXP (address, 0); |
1722 | 1683 |
1723 gcc_assert (GET_CODE (address) == REG); | 1684 gcc_assert (REG_P (address)); |
1724 | 1685 |
1725 fputc ('(', file); | 1686 fputc ('(', file); |
1726 if (pre_dec) | 1687 if (pre_dec) |
1727 fputs ("--", file); | 1688 fputs ("--", file); |
1728 fputs (reg_names [REGNO (address)], file); | 1689 fputs (reg_names [REGNO (address)], file); |
1731 if (offset != 0) | 1692 if (offset != 0) |
1732 fprintf (file, "," HOST_WIDE_INT_PRINT_DEC, offset); | 1693 fprintf (file, "," HOST_WIDE_INT_PRINT_DEC, offset); |
1733 fputc (')', file); | 1694 fputc (')', file); |
1734 } | 1695 } |
1735 | 1696 |
1736 /* Print an operand to an assembler instruction. */ | 1697 /* Worker function for TARGET_PRINT_OPERAND. |
1737 | 1698 |
1738 void | 1699 Print an operand to an assembler instruction. */ |
1700 | |
1701 static void | |
1739 xstormy16_print_operand (FILE *file, rtx x, int code) | 1702 xstormy16_print_operand (FILE *file, rtx x, int code) |
1740 { | 1703 { |
1741 switch (code) | 1704 switch (code) |
1742 { | 1705 { |
1743 case 'B': | 1706 case 'B': |
1746 { | 1709 { |
1747 static int bits_set[8] = { 0, 1, 1, 2, 1, 2, 2, 3 }; | 1710 static int bits_set[8] = { 0, 1, 1, 2, 1, 2, 2, 3 }; |
1748 HOST_WIDE_INT xx = 1; | 1711 HOST_WIDE_INT xx = 1; |
1749 HOST_WIDE_INT l; | 1712 HOST_WIDE_INT l; |
1750 | 1713 |
1751 if (GET_CODE (x) == CONST_INT) | 1714 if (CONST_INT_P (x)) |
1752 xx = INTVAL (x); | 1715 xx = INTVAL (x); |
1753 else | 1716 else |
1754 output_operand_lossage ("'B' operand is not constant"); | 1717 output_operand_lossage ("'B' operand is not constant"); |
1755 | 1718 |
1756 /* GCC sign-extends masks with the MSB set, so we have to | 1719 /* GCC sign-extends masks with the MSB set, so we have to |
1786 | 1749 |
1787 case 'C': | 1750 case 'C': |
1788 /* Print the symbol without a surrounding @fptr(). */ | 1751 /* Print the symbol without a surrounding @fptr(). */ |
1789 if (GET_CODE (x) == SYMBOL_REF) | 1752 if (GET_CODE (x) == SYMBOL_REF) |
1790 assemble_name (file, XSTR (x, 0)); | 1753 assemble_name (file, XSTR (x, 0)); |
1791 else if (GET_CODE (x) == LABEL_REF) | 1754 else if (LABEL_P (x)) |
1792 output_asm_label (x); | 1755 output_asm_label (x); |
1793 else | 1756 else |
1794 xstormy16_print_operand_address (file, x); | 1757 xstormy16_print_operand_address (file, x); |
1795 return; | 1758 return; |
1796 | 1759 |
1799 /* Print the immediate operand less one, preceded by '#'. | 1762 /* Print the immediate operand less one, preceded by '#'. |
1800 For 'O', negate it first. */ | 1763 For 'O', negate it first. */ |
1801 { | 1764 { |
1802 HOST_WIDE_INT xx = 0; | 1765 HOST_WIDE_INT xx = 0; |
1803 | 1766 |
1804 if (GET_CODE (x) == CONST_INT) | 1767 if (CONST_INT_P (x)) |
1805 xx = INTVAL (x); | 1768 xx = INTVAL (x); |
1806 else | 1769 else |
1807 output_operand_lossage ("'o' operand is not constant"); | 1770 output_operand_lossage ("'o' operand is not constant"); |
1808 | 1771 |
1809 if (code == 'O') | 1772 if (code == 'O') |
1817 /* Print the shift mask for bp/bn. */ | 1780 /* Print the shift mask for bp/bn. */ |
1818 { | 1781 { |
1819 HOST_WIDE_INT xx = 1; | 1782 HOST_WIDE_INT xx = 1; |
1820 HOST_WIDE_INT l; | 1783 HOST_WIDE_INT l; |
1821 | 1784 |
1822 if (GET_CODE (x) == CONST_INT) | 1785 if (CONST_INT_P (x)) |
1823 xx = INTVAL (x); | 1786 xx = INTVAL (x); |
1824 else | 1787 else |
1825 output_operand_lossage ("'B' operand is not constant"); | 1788 output_operand_lossage ("'B' operand is not constant"); |
1826 | 1789 |
1827 l = 7 - xx; | 1790 l = 7 - xx; |
1915 fputc ('\n', file); | 1878 fputc ('\n', file); |
1916 } | 1879 } |
1917 } | 1880 } |
1918 | 1881 |
1919 /* Expander for the `call' patterns. | 1882 /* Expander for the `call' patterns. |
1920 INDEX is the index of the switch statement. | 1883 RETVAL is the RTL for the return register or NULL for void functions. |
1921 LOWER_BOUND is a CONST_INT that is the value of INDEX corresponding | 1884 DEST is the function to call, expressed as a MEM. |
1922 to the first table entry. | 1885 COUNTER is ignored. */ |
1923 RANGE is the number of table entries. | |
1924 TABLE is an ADDR_VEC that is the jump table. | |
1925 DEFAULT_LABEL is the address to branch to if INDEX is outside the | |
1926 range LOWER_BOUND to LOWER_BOUND + RANGE - 1. */ | |
1927 | 1886 |
1928 void | 1887 void |
1929 xstormy16_expand_call (rtx retval, rtx dest, rtx counter) | 1888 xstormy16_expand_call (rtx retval, rtx dest, rtx counter) |
1930 { | 1889 { |
1931 rtx call, temp; | 1890 rtx call, temp; |
1932 enum machine_mode mode; | 1891 enum machine_mode mode; |
1933 | 1892 |
1934 gcc_assert (GET_CODE (dest) == MEM); | 1893 gcc_assert (MEM_P (dest)); |
1935 dest = XEXP (dest, 0); | 1894 dest = XEXP (dest, 0); |
1936 | 1895 |
1937 if (! CONSTANT_P (dest) | 1896 if (! CONSTANT_P (dest) && ! REG_P (dest)) |
1938 && GET_CODE (dest) != REG) | |
1939 dest = force_reg (Pmode, dest); | 1897 dest = force_reg (Pmode, dest); |
1940 | 1898 |
1941 if (retval == NULL) | 1899 if (retval == NULL) |
1942 mode = VOIDmode; | 1900 mode = VOIDmode; |
1943 else | 1901 else |
1993 | 1951 |
1994 switch (code) | 1952 switch (code) |
1995 { | 1953 { |
1996 case PLUS: | 1954 case PLUS: |
1997 if (firstloop | 1955 if (firstloop |
1998 && GET_CODE (w_src1) == CONST_INT && INTVAL (w_src1) == 0) | 1956 && CONST_INT_P (w_src1) |
1957 && INTVAL (w_src1) == 0) | |
1999 continue; | 1958 continue; |
2000 | 1959 |
2001 if (firstloop) | 1960 if (firstloop) |
2002 insn = gen_addchi4 (w_dest, w_src0, w_src1); | 1961 insn = gen_addchi4 (w_dest, w_src0, w_src1); |
2003 else | 1962 else |
2026 insn = gen_rtx_PARALLEL (VOIDmode, | 1985 insn = gen_rtx_PARALLEL (VOIDmode, |
2027 gen_rtvec (3, branch, sub, clobber)); | 1986 gen_rtvec (3, branch, sub, clobber)); |
2028 } | 1987 } |
2029 else if (firstloop | 1988 else if (firstloop |
2030 && code != COMPARE | 1989 && code != COMPARE |
2031 && GET_CODE (w_src1) == CONST_INT && INTVAL (w_src1) == 0) | 1990 && CONST_INT_P (w_src1) |
1991 && INTVAL (w_src1) == 0) | |
2032 continue; | 1992 continue; |
2033 else if (firstloop) | 1993 else if (firstloop) |
2034 insn = gen_subchi4 (w_dest, w_src0, w_src1); | 1994 insn = gen_subchi4 (w_dest, w_src0, w_src1); |
2035 else | 1995 else |
2036 insn = gen_subchi5 (w_dest, w_src0, w_src1); | 1996 insn = gen_subchi5 (w_dest, w_src0, w_src1); |
2037 break; | 1997 break; |
2038 | 1998 |
2039 case IOR: | 1999 case IOR: |
2040 case XOR: | 2000 case XOR: |
2041 case AND: | 2001 case AND: |
2042 if (GET_CODE (w_src1) == CONST_INT | 2002 if (CONST_INT_P (w_src1) |
2043 && INTVAL (w_src1) == -(code == AND)) | 2003 && INTVAL (w_src1) == -(code == AND)) |
2044 continue; | 2004 continue; |
2045 | 2005 |
2046 insn = gen_rtx_SET (VOIDmode, w_dest, gen_rtx_fmt_ee (code, mode, | 2006 insn = gen_rtx_SET (VOIDmode, w_dest, gen_rtx_fmt_ee (code, mode, |
2047 w_src0, w_src1)); | 2007 w_src0, w_src1)); |
2077 { | 2037 { |
2078 HOST_WIDE_INT size; | 2038 HOST_WIDE_INT size; |
2079 const char *r0, *r1, *rt; | 2039 const char *r0, *r1, *rt; |
2080 static char r[64]; | 2040 static char r[64]; |
2081 | 2041 |
2082 gcc_assert (GET_CODE (size_r) == CONST_INT | 2042 gcc_assert (CONST_INT_P (size_r) |
2083 && GET_CODE (x) == REG && mode == SImode); | 2043 && REG_P (x) |
2044 && mode == SImode); | |
2045 | |
2084 size = INTVAL (size_r) & (GET_MODE_BITSIZE (mode) - 1); | 2046 size = INTVAL (size_r) & (GET_MODE_BITSIZE (mode) - 1); |
2085 | 2047 |
2086 if (size == 0) | 2048 if (size == 0) |
2087 return ""; | 2049 return ""; |
2088 | 2050 |
2333 i = DECL_FUNCTION_CODE (fndecl); | 2295 i = DECL_FUNCTION_CODE (fndecl); |
2334 code = s16builtins[i].md_code; | 2296 code = s16builtins[i].md_code; |
2335 | 2297 |
2336 for (a = 0; a < 10 && argtree; a++) | 2298 for (a = 0; a < 10 && argtree; a++) |
2337 { | 2299 { |
2338 args[a] = expand_expr (TREE_VALUE (argtree), NULL_RTX, VOIDmode, 0); | 2300 args[a] = expand_normal (TREE_VALUE (argtree)); |
2339 argtree = TREE_CHAIN (argtree); | 2301 argtree = TREE_CHAIN (argtree); |
2340 } | 2302 } |
2341 | 2303 |
2342 for (o = 0; s16builtins[i].arg_ops[o]; o++) | 2304 for (o = 0; s16builtins[i].arg_ops[o]; o++) |
2343 { | 2305 { |
2344 char ao = s16builtins[i].arg_ops[o]; | 2306 char ao = s16builtins[i].arg_ops[o]; |
2345 char c = insn_data[code].operand[o].constraint[0]; | 2307 char c = insn_data[code].operand[o].constraint[0]; |
2346 int omode; | 2308 enum machine_mode omode; |
2347 | 2309 |
2348 copyto[o] = 0; | 2310 copyto[o] = 0; |
2349 | 2311 |
2350 omode = insn_data[code].operand[o].mode; | 2312 omode = (enum machine_mode) insn_data[code].operand[o].mode; |
2351 if (ao == 'r') | 2313 if (ao == 'r') |
2352 op[o] = target ? target : gen_reg_rtx (omode); | 2314 op[o] = target ? target : gen_reg_rtx (omode); |
2353 else if (ao == 't') | 2315 else if (ao == 't') |
2354 op[o] = gen_reg_rtx (omode); | 2316 op[o] = gen_reg_rtx (omode); |
2355 else | 2317 else |
2392 static void | 2354 static void |
2393 combine_bnp (rtx insn) | 2355 combine_bnp (rtx insn) |
2394 { | 2356 { |
2395 int insn_code, regno, need_extend; | 2357 int insn_code, regno, need_extend; |
2396 unsigned int mask; | 2358 unsigned int mask; |
2397 rtx cond, reg, and, load, qireg, mem; | 2359 rtx cond, reg, and_insn, load, qireg, mem; |
2398 enum machine_mode load_mode = QImode; | 2360 enum machine_mode load_mode = QImode; |
2399 enum machine_mode and_mode = QImode; | 2361 enum machine_mode and_mode = QImode; |
2400 rtx shift = NULL_RTX; | 2362 rtx shift = NULL_RTX; |
2401 | 2363 |
2402 insn_code = recog_memoized (insn); | 2364 insn_code = recog_memoized (insn); |
2420 default: | 2382 default: |
2421 return; | 2383 return; |
2422 } | 2384 } |
2423 | 2385 |
2424 reg = XEXP (cond, 0); | 2386 reg = XEXP (cond, 0); |
2425 if (GET_CODE (reg) != REG) | 2387 if (! REG_P (reg)) |
2426 return; | 2388 return; |
2427 regno = REGNO (reg); | 2389 regno = REGNO (reg); |
2428 if (XEXP (cond, 1) != const0_rtx) | 2390 if (XEXP (cond, 1) != const0_rtx) |
2429 return; | 2391 return; |
2430 if (! find_regno_note (insn, REG_DEAD, regno)) | 2392 if (! find_regno_note (insn, REG_DEAD, regno)) |
2433 | 2395 |
2434 if (need_extend) | 2396 if (need_extend) |
2435 { | 2397 { |
2436 /* LT and GE conditionals should have a sign extend before | 2398 /* LT and GE conditionals should have a sign extend before |
2437 them. */ | 2399 them. */ |
2438 for (and = prev_real_insn (insn); and; and = prev_real_insn (and)) | 2400 for (and_insn = prev_real_insn (insn); and_insn; |
2401 and_insn = prev_real_insn (and_insn)) | |
2439 { | 2402 { |
2440 int and_code = recog_memoized (and); | 2403 int and_code = recog_memoized (and_insn); |
2441 | 2404 |
2442 if (and_code == CODE_FOR_extendqihi2 | 2405 if (and_code == CODE_FOR_extendqihi2 |
2443 && rtx_equal_p (SET_DEST (PATTERN (and)), reg) | 2406 && rtx_equal_p (SET_DEST (PATTERN (and_insn)), reg) |
2444 && rtx_equal_p (XEXP (SET_SRC (PATTERN (and)), 0), qireg)) | 2407 && rtx_equal_p (XEXP (SET_SRC (PATTERN (and_insn)), 0), qireg)) |
2445 break; | 2408 break; |
2446 | 2409 |
2447 if (and_code == CODE_FOR_movhi_internal | 2410 if (and_code == CODE_FOR_movhi_internal |
2448 && rtx_equal_p (SET_DEST (PATTERN (and)), reg)) | 2411 && rtx_equal_p (SET_DEST (PATTERN (and_insn)), reg)) |
2449 { | 2412 { |
2450 /* This is for testing bit 15. */ | 2413 /* This is for testing bit 15. */ |
2451 and = insn; | 2414 and_insn = insn; |
2452 break; | 2415 break; |
2453 } | 2416 } |
2454 | 2417 |
2455 if (reg_mentioned_p (reg, and)) | 2418 if (reg_mentioned_p (reg, and_insn)) |
2456 return; | 2419 return; |
2457 | 2420 |
2458 if (GET_CODE (and) != NOTE | 2421 if (GET_CODE (and_insn) != NOTE |
2459 && GET_CODE (and) != INSN) | 2422 && GET_CODE (and_insn) != INSN) |
2460 return; | 2423 return; |
2461 } | 2424 } |
2462 } | 2425 } |
2463 else | 2426 else |
2464 { | 2427 { |
2465 /* EQ and NE conditionals have an AND before them. */ | 2428 /* EQ and NE conditionals have an AND before them. */ |
2466 for (and = prev_real_insn (insn); and; and = prev_real_insn (and)) | 2429 for (and_insn = prev_real_insn (insn); and_insn; |
2430 and_insn = prev_real_insn (and_insn)) | |
2467 { | 2431 { |
2468 if (recog_memoized (and) == CODE_FOR_andhi3 | 2432 if (recog_memoized (and_insn) == CODE_FOR_andhi3 |
2469 && rtx_equal_p (SET_DEST (PATTERN (and)), reg) | 2433 && rtx_equal_p (SET_DEST (PATTERN (and_insn)), reg) |
2470 && rtx_equal_p (XEXP (SET_SRC (PATTERN (and)), 0), reg)) | 2434 && rtx_equal_p (XEXP (SET_SRC (PATTERN (and_insn)), 0), reg)) |
2471 break; | 2435 break; |
2472 | 2436 |
2473 if (reg_mentioned_p (reg, and)) | 2437 if (reg_mentioned_p (reg, and_insn)) |
2474 return; | 2438 return; |
2475 | 2439 |
2476 if (GET_CODE (and) != NOTE | 2440 if (GET_CODE (and_insn) != NOTE |
2477 && GET_CODE (and) != INSN) | 2441 && GET_CODE (and_insn) != INSN) |
2478 return; | 2442 return; |
2479 } | 2443 } |
2480 | 2444 |
2481 if (and) | 2445 if (and_insn) |
2482 { | 2446 { |
2483 /* Some mis-optimizations by GCC can generate a RIGHT-SHIFT | 2447 /* Some mis-optimizations by GCC can generate a RIGHT-SHIFT |
2484 followed by an AND like this: | 2448 followed by an AND like this: |
2485 | 2449 |
2486 (parallel [(set (reg:HI r7) (lshiftrt:HI (reg:HI r7) (const_int 3))) | 2450 (parallel [(set (reg:HI r7) (lshiftrt:HI (reg:HI r7) (const_int 3))) |
2487 (clobber (reg:BI carry))] | 2451 (clobber (reg:BI carry))] |
2488 | 2452 |
2489 (set (reg:HI r7) (and:HI (reg:HI r7) (const_int 1))) | 2453 (set (reg:HI r7) (and:HI (reg:HI r7) (const_int 1))) |
2490 | 2454 |
2491 Attempt to detect this here. */ | 2455 Attempt to detect this here. */ |
2492 for (shift = prev_real_insn (and); shift; shift = prev_real_insn (shift)) | 2456 for (shift = prev_real_insn (and_insn); shift; |
2457 shift = prev_real_insn (shift)) | |
2493 { | 2458 { |
2494 if (recog_memoized (shift) == CODE_FOR_lshrhi3 | 2459 if (recog_memoized (shift) == CODE_FOR_lshrhi3 |
2495 && rtx_equal_p (SET_DEST (XVECEXP (PATTERN (shift), 0, 0)), reg) | 2460 && rtx_equal_p (SET_DEST (XVECEXP (PATTERN (shift), 0, 0)), reg) |
2496 && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (shift), 0, 0)), 0), reg)) | 2461 && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (shift), 0, 0)), 0), reg)) |
2497 break; | 2462 break; |
2504 break; | 2469 break; |
2505 } | 2470 } |
2506 } | 2471 } |
2507 } | 2472 } |
2508 } | 2473 } |
2509 if (!and) | 2474 if (!and_insn) |
2510 return; | 2475 return; |
2511 | 2476 |
2512 for (load = shift ? prev_real_insn (shift) : prev_real_insn (and); | 2477 for (load = shift ? prev_real_insn (shift) : prev_real_insn (and_insn); |
2513 load; | 2478 load; |
2514 load = prev_real_insn (load)) | 2479 load = prev_real_insn (load)) |
2515 { | 2480 { |
2516 int load_code = recog_memoized (load); | 2481 int load_code = recog_memoized (load); |
2517 | 2482 |
2563 if (GET_CODE (mem) == ZERO_EXTEND) | 2528 if (GET_CODE (mem) == ZERO_EXTEND) |
2564 mem = XEXP (mem, 0); | 2529 mem = XEXP (mem, 0); |
2565 } | 2530 } |
2566 else | 2531 else |
2567 { | 2532 { |
2568 if (!xstormy16_onebit_set_operand (XEXP (SET_SRC (PATTERN (and)), 1), load_mode)) | 2533 if (!xstormy16_onebit_set_operand (XEXP (SET_SRC (PATTERN (and_insn)), 1), |
2534 load_mode)) | |
2569 return; | 2535 return; |
2570 | 2536 |
2571 mask = (int) INTVAL (XEXP (SET_SRC (PATTERN (and)), 1)); | 2537 mask = (int) INTVAL (XEXP (SET_SRC (PATTERN (and_insn)), 1)); |
2572 | 2538 |
2573 if (shift) | 2539 if (shift) |
2574 mask <<= INTVAL (XEXP (SET_SRC (XVECEXP (PATTERN (shift), 0, 0)), 1)); | 2540 mask <<= INTVAL (XEXP (SET_SRC (XVECEXP (PATTERN (shift), 0, 0)), 1)); |
2575 } | 2541 } |
2576 | 2542 |
2592 XEXP (cond, 0) = gen_rtx_AND (and_mode, mem, GEN_INT (mask)); | 2558 XEXP (cond, 0) = gen_rtx_AND (and_mode, mem, GEN_INT (mask)); |
2593 | 2559 |
2594 INSN_CODE (insn) = -1; | 2560 INSN_CODE (insn) = -1; |
2595 delete_insn (load); | 2561 delete_insn (load); |
2596 | 2562 |
2597 if (and != insn) | 2563 if (and_insn != insn) |
2598 delete_insn (and); | 2564 delete_insn (and_insn); |
2599 | 2565 |
2600 if (shift != NULL_RTX) | 2566 if (shift != NULL_RTX) |
2601 delete_insn (shift); | 2567 delete_insn (shift); |
2602 } | 2568 } |
2603 | 2569 |
2620 xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) | 2586 xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) |
2621 { | 2587 { |
2622 const HOST_WIDE_INT size = int_size_in_bytes (type); | 2588 const HOST_WIDE_INT size = int_size_in_bytes (type); |
2623 return (size == -1 || size > UNITS_PER_WORD * NUM_ARGUMENT_REGISTERS); | 2589 return (size == -1 || size > UNITS_PER_WORD * NUM_ARGUMENT_REGISTERS); |
2624 } | 2590 } |
2591 | |
2592 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
2593 static const struct default_options xstorym16_option_optimization_table[] = | |
2594 { | |
2595 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
2596 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
2597 }; | |
2625 | 2598 |
2626 #undef TARGET_ASM_ALIGNED_HI_OP | 2599 #undef TARGET_ASM_ALIGNED_HI_OP |
2627 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" | 2600 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" |
2628 #undef TARGET_ASM_ALIGNED_SI_OP | 2601 #undef TARGET_ASM_ALIGNED_SI_OP |
2629 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" | 2602 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" |
2637 #undef TARGET_ASM_OUTPUT_MI_THUNK | 2610 #undef TARGET_ASM_OUTPUT_MI_THUNK |
2638 #define TARGET_ASM_OUTPUT_MI_THUNK xstormy16_asm_output_mi_thunk | 2611 #define TARGET_ASM_OUTPUT_MI_THUNK xstormy16_asm_output_mi_thunk |
2639 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK | 2612 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK |
2640 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall | 2613 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall |
2641 | 2614 |
2615 #undef TARGET_PRINT_OPERAND | |
2616 #define TARGET_PRINT_OPERAND xstormy16_print_operand | |
2617 #undef TARGET_PRINT_OPERAND_ADDRESS | |
2618 #define TARGET_PRINT_OPERAND_ADDRESS xstormy16_print_operand_address | |
2619 | |
2620 #undef TARGET_MEMORY_MOVE_COST | |
2621 #define TARGET_MEMORY_MOVE_COST xstormy16_memory_move_cost | |
2642 #undef TARGET_RTX_COSTS | 2622 #undef TARGET_RTX_COSTS |
2643 #define TARGET_RTX_COSTS xstormy16_rtx_costs | 2623 #define TARGET_RTX_COSTS xstormy16_rtx_costs |
2644 #undef TARGET_ADDRESS_COST | 2624 #undef TARGET_ADDRESS_COST |
2645 #define TARGET_ADDRESS_COST xstormy16_address_cost | 2625 #define TARGET_ADDRESS_COST xstormy16_address_cost |
2646 | 2626 |
2654 #undef TARGET_PROMOTE_FUNCTION_MODE | 2634 #undef TARGET_PROMOTE_FUNCTION_MODE |
2655 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote | 2635 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote |
2656 #undef TARGET_PROMOTE_PROTOTYPES | 2636 #undef TARGET_PROMOTE_PROTOTYPES |
2657 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true | 2637 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true |
2658 | 2638 |
2639 #undef TARGET_FUNCTION_ARG | |
2640 #define TARGET_FUNCTION_ARG xstormy16_function_arg | |
2641 #undef TARGET_FUNCTION_ARG_ADVANCE | |
2642 #define TARGET_FUNCTION_ARG_ADVANCE xstormy16_function_arg_advance | |
2643 | |
2659 #undef TARGET_RETURN_IN_MEMORY | 2644 #undef TARGET_RETURN_IN_MEMORY |
2660 #define TARGET_RETURN_IN_MEMORY xstormy16_return_in_memory | 2645 #define TARGET_RETURN_IN_MEMORY xstormy16_return_in_memory |
2646 #undef TARGET_FUNCTION_VALUE | |
2647 #define TARGET_FUNCTION_VALUE xstormy16_function_value | |
2648 #undef TARGET_LIBCALL_VALUE | |
2649 #define TARGET_LIBCALL_VALUE xstormy16_libcall_value | |
2650 #undef TARGET_FUNCTION_VALUE_REGNO_P | |
2651 #define TARGET_FUNCTION_VALUE_REGNO_P xstormy16_function_value_regno_p | |
2661 | 2652 |
2662 #undef TARGET_MACHINE_DEPENDENT_REORG | 2653 #undef TARGET_MACHINE_DEPENDENT_REORG |
2663 #define TARGET_MACHINE_DEPENDENT_REORG xstormy16_reorg | 2654 #define TARGET_MACHINE_DEPENDENT_REORG xstormy16_reorg |
2664 | 2655 |
2656 #undef TARGET_PREFERRED_RELOAD_CLASS | |
2657 #define TARGET_PREFERRED_RELOAD_CLASS xstormy16_preferred_reload_class | |
2658 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS | |
2659 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xstormy16_preferred_reload_class | |
2660 | |
2665 #undef TARGET_LEGITIMATE_ADDRESS_P | 2661 #undef TARGET_LEGITIMATE_ADDRESS_P |
2666 #define TARGET_LEGITIMATE_ADDRESS_P xstormy16_legitimate_address_p | 2662 #define TARGET_LEGITIMATE_ADDRESS_P xstormy16_legitimate_address_p |
2663 #undef TARGET_MODE_DEPENDENT_ADDRESS_P | |
2664 #define TARGET_MODE_DEPENDENT_ADDRESS_P xstormy16_mode_dependent_address_p | |
2667 | 2665 |
2668 #undef TARGET_CAN_ELIMINATE | 2666 #undef TARGET_CAN_ELIMINATE |
2669 #define TARGET_CAN_ELIMINATE xstormy16_can_eliminate | 2667 #define TARGET_CAN_ELIMINATE xstormy16_can_eliminate |
2670 | 2668 |
2671 #undef TARGET_TRAMPOLINE_INIT | 2669 #undef TARGET_TRAMPOLINE_INIT |
2672 #define TARGET_TRAMPOLINE_INIT xstormy16_trampoline_init | 2670 #define TARGET_TRAMPOLINE_INIT xstormy16_trampoline_init |
2673 | 2671 |
2672 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
2673 #define TARGET_OPTION_OPTIMIZATION_TABLE xstorym16_option_optimization_table | |
2674 | |
2674 struct gcc_target targetm = TARGET_INITIALIZER; | 2675 struct gcc_target targetm = TARGET_INITIALIZER; |
2675 | 2676 |
2676 #include "gt-stormy16.h" | 2677 #include "gt-stormy16.h" |