comparison gcc/config/avr/avr.md @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 ;; -*- Mode: Scheme -*- 1 ;; -*- Mode: Scheme -*-
2 ;; Machine description for GNU compiler, 2 ;; Machine description for GNU compiler,
3 ;; for ATMEL AVR micro controllers. 3 ;; for ATMEL AVR micro controllers.
4 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 4 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
5 ;; 2009 Free Software Foundation, Inc. 5 ;; 2009, 2010 Free Software Foundation, Inc.
6 ;; Contributed by Denis Chertykov (chertykov@gmail.com) 6 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
7 7
8 ;; This file is part of GCC. 8 ;; This file is part of GCC.
9 9
10 ;; GCC is free software; you can redistribute it and/or modify 10 ;; GCC is free software; you can redistribute it and/or modify
119 (const_int 2))) 119 (const_int 2)))
120 120
121 ;; Define mode iterator 121 ;; Define mode iterator
122 (define_mode_iterator QISI [(QI "") (HI "") (SI "")]) 122 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
123 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")]) 123 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
124 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
125 (define_mode_iterator HISI [(HI "") (SI "")])
124 126
125 ;;======================================================================== 127 ;;========================================================================
126 ;; The following is used by nonlocal_goto and setjmp. 128 ;; The following is used by nonlocal_goto and setjmp.
127 ;; The receiver pattern will create no instructions since internally 129 ;; The receiver pattern will create no instructions since internally
128 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28 130 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
1483 (rotate:QI (match_operand:QI 1 "register_operand" "") 1485 (rotate:QI (match_operand:QI 1 "register_operand" "")
1484 (match_operand:QI 2 "const_int_operand" "")))] 1486 (match_operand:QI 2 "const_int_operand" "")))]
1485 "" 1487 ""
1486 " 1488 "
1487 { 1489 {
1488 if (INTVAL (operands[2]) != 4) 1490 if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
1489 FAIL; 1491 FAIL;
1490 }") 1492 }")
1491 1493
1492 (define_insn "*rotlqi3_4" 1494 (define_insn "*rotlqi3_4"
1493 [(set (match_operand:QI 0 "register_operand" "=r") 1495 [(set (match_operand:QI 0 "register_operand" "=r")
1496 "" 1498 ""
1497 "swap %0" 1499 "swap %0"
1498 [(set_attr "length" "1") 1500 [(set_attr "length" "1")
1499 (set_attr "cc" "none")]) 1501 (set_attr "cc" "none")])
1500 1502
1501 (define_expand "rotlhi3" 1503 ;; Split all rotates of HI,SI and DImode registers where rotation is by
1502 [(set (match_operand:HI 0 "register_operand" "") 1504 ;; a whole number of bytes. The split creates the appropriate moves and
1503 (rotate:HI (match_operand:HI 1 "register_operand" "") 1505 ;; considers all overlap situations. DImode is split before reload.
1504 (match_operand:HI 2 "const_int_operand" "")))] 1506
1507 ;; HImode does not need scratch. Use attribute for this constraint.
1508 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
1509
1510 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
1511 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
1512
1513 (define_expand "rotl<mode>3"
1514 [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
1515 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
1516 (match_operand:VOID 2 "const_int_operand" "")))
1517 (clobber (match_operand 3 ""))])]
1505 "" 1518 ""
1506 " 1519 "
1507 { 1520 {
1508 if (INTVAL (operands[2]) != 8) 1521 if (CONST_INT_P (operands[2]) && 0 == (INTVAL (operands[2]) % 8))
1522 {
1523 if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
1524 operands[3] = gen_reg_rtx (<rotsmode>mode);
1525 else
1526 operands[3] = gen_reg_rtx (QImode);
1527 }
1528 else
1509 FAIL; 1529 FAIL;
1510 }") 1530 }")
1511 1531
1512 (define_insn_and_split "*rotlhi3_8" 1532
1513 [(set (match_operand:HI 0 "register_operand" "=r") 1533 ;; Overlapping non-HImode registers often (but not always) need a scratch.
1514 (rotate:HI (match_operand:HI 1 "register_operand" "r") 1534 ;; The best we can do is use early clobber alternative "#&r" so that
1515 (const_int 8)))] 1535 ;; completely non-overlapping operands dont get a scratch but # so register
1516 "" 1536 ;; allocation does not prefer non-overlapping.
1517 "mov __tmp_reg__,%A0 1537
1518 mov %A0,%B0 1538
1519 mov %B0, __tmp_reg__" 1539 ; Split word aligned rotates using scratch that is mode dependent.
1520 "reload_completed 1540 (define_insn_and_split "*rotw<mode>"
1521 && REGNO (operands[0]) != REGNO (operands[1])" 1541 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1522 [(set (match_dup 2) (match_dup 5)) 1542 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1523 (set (match_dup 3) (match_dup 4))] 1543 (match_operand 2 "immediate_operand" "n,n,n")))
1524 "operands[2] = gen_lowpart (QImode, operands[0]); 1544 (clobber (match_operand:<rotsmode> 3 "register_operand" "=<rotx>" ))]
1525 operands[3] = gen_highpart (QImode, operands[0]); 1545 "(CONST_INT_P (operands[2]) &&
1526 1546 (0 == (INTVAL (operands[2]) % 16) && AVR_HAVE_MOVW))"
1527 operands[4] = gen_lowpart (QImode, operands[1]); 1547 "#"
1528 operands[5] = gen_highpart (QImode, operands[1]);" 1548 "&& (reload_completed || <MODE>mode == DImode)"
1529 [(set_attr "length" "3")
1530 (set_attr "cc" "none")])
1531
1532 (define_expand "rotlsi3"
1533 [(set (match_operand:SI 0 "register_operand" "")
1534 (rotate:SI (match_operand:SI 1 "register_operand" "")
1535 (match_operand:SI 2 "const_int_operand" "")))]
1536 ""
1537 "
1538 {
1539 if (INTVAL (operands[2]) != 8
1540 || INTVAL (operands[2]) != 16
1541 || INTVAL (operands[2]) != 24)
1542 FAIL;
1543 }")
1544
1545 (define_insn_and_split "*rotlsi3_16"
1546 [(set (match_operand:SI 0 "register_operand" "=r")
1547 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1548 (const_int 16)))]
1549 ""
1550 "{mov __tmp_reg__,%A1\;mov %A0,%C1\;mov %C0, __tmp_reg__\;mov __tmp_reg__,%B1\;mov %B0,%D1\;mov %D0, __tmp_reg__|movw __tmp_reg__,%A1\;movw %A0,%C1\;movw %C0, __tmp_reg__\;clr __zero_reg__}"
1551 "reload_completed
1552 && REGNO (operands[0]) != REGNO (operands[1])"
1553 [(set (match_dup 2) (match_dup 5))
1554 (set (match_dup 3) (match_dup 4))]
1555 "unsigned int si_lo_off = subreg_lowpart_offset (HImode, SImode);
1556 unsigned int si_hi_off = subreg_highpart_offset (HImode, SImode);
1557
1558 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, si_lo_off);
1559 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, si_hi_off);
1560
1561 operands[4] = simplify_gen_subreg (HImode, operands[1], SImode, si_lo_off);
1562 operands[5] = simplify_gen_subreg (HImode, operands[1], SImode, si_hi_off);
1563
1564 if (REGNO (operands[0]) == REGNO(operands[1]) + 2)
1565 {
1566 emit_move_insn (operands[3], operands[4]);
1567 DONE;
1568 }
1569 else if (REGNO (operands[0]) == REGNO(operands[1]) - 2)
1570 {
1571 emit_move_insn (operands[2], operands[5]);
1572 DONE;
1573 }"
1574 [(set (attr "length") (if_then_else (eq_attr "mcu_have_movw" "yes")
1575 (const_int 4)
1576 (const_int 6)))
1577 (set (attr "cc") (if_then_else (eq_attr "mcu_have_movw" "yes")
1578 (const_string "clobber")
1579 (const_string "none")))])
1580
1581 (define_insn_and_split "*rotlsi3_8"
1582 [(set (match_operand:SI 0 "register_operand" "=r")
1583 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1584 (const_int 8)))]
1585 ""
1586 "mov __tmp_reg__,%D1
1587 mov %D0,%C1
1588 mov %C0,%B1
1589 mov %B0,%A1
1590 mov %A0, __tmp_reg__"
1591 "reload_completed
1592 && REGNO (operands[0]) != REGNO (operands[1])"
1593 [(const_int 0)] 1549 [(const_int 0)]
1594 "unsigned int si_lo_off = subreg_lowpart_offset (HImode, SImode); 1550 "avr_rotate_bytes (operands);
1595 unsigned int si_hi_off = subreg_highpart_offset (HImode, SImode); 1551 DONE;"
1596 unsigned int hi_lo_off = subreg_lowpart_offset (QImode, HImode); 1552 )
1597 unsigned int hi_hi_off = subreg_highpart_offset (QImode, HImode); 1553
1598 1554
1599 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, si_lo_off); 1555 ; Split byte aligned rotates using scratch that is always QI mode.
1600 operands[4] = simplify_gen_subreg (HImode, operands[0], SImode, si_hi_off); 1556 (define_insn_and_split "*rotb<mode>"
1601 operands[3] = simplify_gen_subreg (QImode, operands[2], HImode, hi_hi_off); 1557 [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1602 operands[2] = simplify_gen_subreg (QImode, operands[2], HImode, hi_lo_off); 1558 (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1603 operands[5] = simplify_gen_subreg (QImode, operands[4], HImode, hi_hi_off); 1559 (match_operand 2 "immediate_operand" "n,n,n")))
1604 operands[4] = simplify_gen_subreg (QImode, operands[4], HImode, hi_lo_off); 1560 (clobber (match_operand:QI 3 "register_operand" "=<rotx>" ))]
1605 1561 "(CONST_INT_P (operands[2]) &&
1606 operands[6] = simplify_gen_subreg (HImode, operands[1], SImode, si_lo_off); 1562 (8 == (INTVAL (operands[2]) % 16)
1607 operands[8] = simplify_gen_subreg (HImode, operands[1], SImode, si_hi_off); 1563 || (!AVR_HAVE_MOVW && 0 == (INTVAL (operands[2]) % 16))))"
1608 operands[7] = simplify_gen_subreg (QImode, operands[6], HImode, hi_hi_off); 1564 "#"
1609 operands[6] = simplify_gen_subreg (QImode, operands[6], HImode, hi_lo_off); 1565 "&& (reload_completed || <MODE>mode == DImode)"
1610 operands[9] = simplify_gen_subreg (QImode, operands[8], HImode, hi_hi_off);
1611 operands[8] = simplify_gen_subreg (QImode, operands[8], HImode, hi_lo_off);
1612
1613 if (REGNO (operands[0]) < REGNO(operands[1]))
1614 {
1615 emit_move_insn (operands[2], operands[9]);
1616 emit_move_insn (operands[3], operands[6]);
1617 emit_move_insn (operands[4], operands[7]);
1618 emit_move_insn (operands[5], operands[8]);
1619 }
1620 else
1621 {
1622 emit_move_insn (operands[5], operands[8]);
1623 emit_move_insn (operands[2], operands[9]);
1624 emit_move_insn (operands[4], operands[7]);
1625 emit_move_insn (operands[3], operands[6]);
1626 }
1627 DONE;"
1628 [(set_attr "length" "5")
1629 (set_attr "cc" "none")])
1630
1631 (define_insn_and_split "*rotlsi3_24"
1632 [(set (match_operand:SI 0 "register_operand" "=r")
1633 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1634 (const_int 24)))]
1635 ""
1636 "mov __tmp_reg__,%A1
1637 mov %A0,%B1
1638 mov %B0,%C1
1639 mov %C0,%D1
1640 mov %D0, __tmp_reg__"
1641 "reload_completed
1642 && REGNO (operands[0]) != REGNO (operands[1])"
1643 [(const_int 0)] 1566 [(const_int 0)]
1644 "unsigned int si_lo_off = subreg_lowpart_offset (HImode, SImode); 1567 "avr_rotate_bytes (operands);
1645 unsigned int si_hi_off = subreg_highpart_offset (HImode, SImode); 1568 DONE;"
1646 unsigned int hi_lo_off = subreg_lowpart_offset (QImode, HImode); 1569 )
1647 unsigned int hi_hi_off = subreg_highpart_offset (QImode, HImode); 1570
1648
1649 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, si_lo_off);
1650 operands[4] = simplify_gen_subreg (HImode, operands[0], SImode, si_hi_off);
1651 operands[3] = simplify_gen_subreg (QImode, operands[2], HImode, hi_hi_off);
1652 operands[2] = simplify_gen_subreg (QImode, operands[2], HImode, hi_lo_off);
1653 operands[5] = simplify_gen_subreg (QImode, operands[4], HImode, hi_hi_off);
1654 operands[4] = simplify_gen_subreg (QImode, operands[4], HImode, hi_lo_off);
1655
1656 operands[6] = simplify_gen_subreg (HImode, operands[1], SImode, si_lo_off);
1657 operands[8] = simplify_gen_subreg (HImode, operands[1], SImode, si_hi_off);
1658 operands[7] = simplify_gen_subreg (QImode, operands[6], HImode, hi_hi_off);
1659 operands[6] = simplify_gen_subreg (QImode, operands[6], HImode, hi_lo_off);
1660 operands[9] = simplify_gen_subreg (QImode, operands[8], HImode, hi_hi_off);
1661 operands[8] = simplify_gen_subreg (QImode, operands[8], HImode, hi_lo_off);
1662
1663 if (REGNO (operands[0]) < REGNO(operands[1]))
1664 {
1665 emit_move_insn (operands[2], operands[7]);
1666 emit_move_insn (operands[5], operands[6]);
1667 emit_move_insn (operands[3], operands[8]);
1668 emit_move_insn (operands[4], operands[9]);
1669 }
1670 else
1671 {
1672 emit_move_insn (operands[5], operands[6]);
1673 emit_move_insn (operands[4], operands[9]);
1674 emit_move_insn (operands[3], operands[8]);
1675 emit_move_insn (operands[2], operands[7]);
1676 }
1677 DONE;"
1678 [(set_attr "length" "5")
1679 (set_attr "cc" "none")])
1680 1571
1681 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << << 1572 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1682 ;; arithmetic shift left 1573 ;; arithmetic shift left
1683 1574
1684 (define_expand "ashlqi3" 1575 (define_expand "ashlqi3"