Mercurial > hg > CbC > CbC_gcc
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" |