re PR target/52261 ([avr] Add support for AVR Xmega cores)
libgcc/ PR target/52261 * config/avr/lib1funcs.S (__prologue_saves__): Handle AVR_XMEGA (__epilogue_restores__): Ditto. gcc/ PR target/52261 * config/avr/avr-devices.c (avr_arch_types): Add avrxmega2, avrxmega4, avrxmega5, avrxmega6, avrxmega7. Rewrite initializers for .macro. * config/avr/avr-mcus.def (AVR_MCU): Add known MCUs: avrxmega2: atxmega16a4, atxmega16d4, atxmega16x1, atxmega32a4 atxmega32d4, atxmega32x1. avrxmega4: atxmega64a3, atxmega64d3. avrxmega5: atxmega64a1, atxmega64a1u. avrxmega6: atxmega128a3, atxmega128d3, atxmega192a3, atxmega192d3, atxmega256a3, atxmega256a3b, atxmega256a3bu, atxmega256d3. avrxmega7: atxmega128a1, atxmega128a1u. * config/avr/multilib.h: Regenerate. * config/avr/t-multilib: Regenerate. * config/avr/avr-tables.opt: Regenerate. * config/avr/avr.h (enum avr_arch): Add: ARCH_AVRXMEGA2, ARCH_AVRXMEGA4, ARCH_AVRXMEGA5, ARCH_AVRXMEGA6, ARCH_AVRXMEGA7. (struct base_arch_s): Rename reserved to xmega_p. Rename reserved2 to have_rampd. (AVR_XMEGA): New define. (AVR_HAVE_RAMPD, AVR_HAVE_RAMPX, AVR_HAVE_RAMPY): New defines. (AVR_HAVE_RAMPZ): Change definition to fit xmega. * config/avr/predicates.md (io_address_operand): Take into account SFR offset. (low_io_address_operand): Ditto. (high_io_address_operand): Ditto. * config/avr/avr.md (isa): Add alternatives no_xmega, xmega. (enabled, movhi_sp_r): Use them. * config/avr/avr-c.c (avr_cpu_cpp_builtins): Use cpp_define_formatted to built-in define __AVR_ARCH__. (__AVR_XMEGA__): New built-in define. (__AVR_HAVE_RAMPD__): New built-in define. (__AVR_HAVE_RAMPX__): New built-in define. (__AVR_HAVE_RAMPY__): New built-in define. (__AVR_HAVE_RAMPZ__): Change condition when to built-in define it. * config/avr/avr.c (avr_addr_t): Add ccp, rampd, rampx, rampy. (avr_option_override): Initialize them. (sreg_rtx, rampd_rtx, rampx_rtx, rampy_rtx): New GTY rtx. (avr_init_expanders): Initialize them. No more block several calls. (emit_push_sfr): New static function. (avr_prologue_setup_frame): Use it to push SREG, RAMPD/X/Y/Z as needed. Handle AVR_XMEGA. (expand_epilogue): Handle AVR_XMEGA. Pop RAMPD/X/Y/Z as needed. (avr_print_operand): Print addreeses as symbols for RAMPX, RAMPY, RAMPD, CCP. (output_movhi): Handle AVR_XMEGA when writing to SP. (avr_out_movhi_mr_r_xmega): New static function. (out_movhi_mr_r): Forward to avr_out_movhi_mr_r_xmega for AVR_XMEGA. (avr_file_start): Print symbol defines for __RAMPX__, __RAMPY__, __RAMPD__, __CCP__ as needed. Co-Authored-By: Anatoly Sokolov <aesok@post.ru> Co-Authored-By: Eric Weddington <eric.weddington@atmel.com> From-SVN: r184269
This commit is contained in:
parent
28db21ee45
commit
2da8c1adcf
13 changed files with 575 additions and 100 deletions
|
@ -1,3 +1,60 @@
|
|||
2012-01-15 Georg-Johann Lay <avr@gjlay.de>
|
||||
Anatoly Sokolov <aesok@post.ru>
|
||||
Eric Weddington <eric.weddington@atmel.com>
|
||||
|
||||
PR target/52261
|
||||
* config/avr/avr-devices.c (avr_arch_types): Add avrxmega2,
|
||||
avrxmega4, avrxmega5, avrxmega6, avrxmega7.
|
||||
Rewrite initializers for .macro.
|
||||
* config/avr/avr-mcus.def (AVR_MCU): Add known MCUs:
|
||||
avrxmega2: atxmega16a4, atxmega16d4, atxmega16x1, atxmega32a4
|
||||
atxmega32d4, atxmega32x1.
|
||||
avrxmega4: atxmega64a3, atxmega64d3.
|
||||
avrxmega5: atxmega64a1, atxmega64a1u.
|
||||
avrxmega6: atxmega128a3, atxmega128d3, atxmega192a3, atxmega192d3,
|
||||
atxmega256a3, atxmega256a3b, atxmega256a3bu, atxmega256d3.
|
||||
avrxmega7: atxmega128a1, atxmega128a1u.
|
||||
* config/avr/avr.h (enum avr_arch): Add: ARCH_AVRXMEGA2,
|
||||
ARCH_AVRXMEGA4, ARCH_AVRXMEGA5, ARCH_AVRXMEGA6, ARCH_AVRXMEGA7.
|
||||
(struct base_arch_s): Rename reserved to xmega_p.
|
||||
Rename reserved2 to have_rampd.
|
||||
(AVR_XMEGA): New define.
|
||||
(AVR_HAVE_RAMPD, AVR_HAVE_RAMPX, AVR_HAVE_RAMPY): New defines.
|
||||
(AVR_HAVE_RAMPZ): Change definition to fit xmega.
|
||||
* config/avr/predicates.md (io_address_operand): Take into
|
||||
account SFR offset.
|
||||
(low_io_address_operand): Ditto.
|
||||
(high_io_address_operand): Ditto.
|
||||
* config/avr/avr.md (isa): Add alternatives no_xmega, xmega.
|
||||
(enabled, movhi_sp_r): Use them.
|
||||
* config/avr/avr-c.c (avr_cpu_cpp_builtins): Use
|
||||
cpp_define_formatted to built-in define __AVR_ARCH__.
|
||||
(__AVR_XMEGA__): New built-in define.
|
||||
(__AVR_HAVE_RAMPD__): New built-in define.
|
||||
(__AVR_HAVE_RAMPX__): New built-in define.
|
||||
(__AVR_HAVE_RAMPY__): New built-in define.
|
||||
(__AVR_HAVE_RAMPZ__): Change condition when to built-in define it.
|
||||
|
||||
* config/avr/avr.c (avr_addr_t): Add ccp, rampd, rampx, rampy.
|
||||
(avr_option_override): Initialize them.
|
||||
(sreg_rtx, rampd_rtx, rampx_rtx, rampy_rtx): New GTY rtx.
|
||||
(avr_init_expanders): Initialize them. No more block several calls.
|
||||
(emit_push_sfr): New static function.
|
||||
(avr_prologue_setup_frame): Use it to push SREG, RAMPD/X/Y/Z as needed.
|
||||
Handle AVR_XMEGA.
|
||||
(expand_epilogue): Handle AVR_XMEGA. Pop RAMPD/X/Y/Z as needed.
|
||||
(avr_print_operand): Print addreeses as symbols for
|
||||
RAMPX, RAMPY, RAMPD, CCP.
|
||||
(output_movhi): Handle AVR_XMEGA when writing to SP.
|
||||
(avr_out_movhi_mr_r_xmega): New static function.
|
||||
(out_movhi_mr_r): Forward to avr_out_movhi_mr_r_xmega for AVR_XMEGA.
|
||||
(avr_file_start): Print symbol defines for __RAMPX__, __RAMPY__,
|
||||
__RAMPD__, __CCP__ as needed.
|
||||
|
||||
* config/avr/multilib.h: Regenerate.
|
||||
* config/avr/t-multilib: Regenerate.
|
||||
* config/avr/avr-tables.opt: Regenerate.
|
||||
|
||||
2012-02-15 Tobias Grosser <grosser@fim.uni-passau.de>
|
||||
|
||||
PR tree-optimization/50561
|
||||
|
|
|
@ -77,23 +77,21 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
|
|||
builtin_define_std ("AVR");
|
||||
|
||||
if (avr_current_arch->macro)
|
||||
cpp_define (pfile, avr_current_arch->macro);
|
||||
cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_current_arch->macro);
|
||||
if (avr_extra_arch_macro)
|
||||
cpp_define (pfile, avr_extra_arch_macro);
|
||||
if (avr_current_arch->have_elpm)
|
||||
cpp_define (pfile, "__AVR_HAVE_RAMPZ__");
|
||||
if (avr_current_arch->have_elpm)
|
||||
cpp_define (pfile, "__AVR_HAVE_ELPM__");
|
||||
if (avr_current_arch->have_elpmx)
|
||||
cpp_define (pfile, "__AVR_HAVE_ELPMX__");
|
||||
if (avr_current_arch->have_movw_lpmx)
|
||||
{
|
||||
cpp_define (pfile, "__AVR_HAVE_MOVW__");
|
||||
cpp_define (pfile, "__AVR_HAVE_LPMX__");
|
||||
}
|
||||
if (AVR_HAVE_RAMPD) cpp_define (pfile, "__AVR_HAVE_RAMPD__");
|
||||
if (AVR_HAVE_RAMPX) cpp_define (pfile, "__AVR_HAVE_RAMPX__");
|
||||
if (AVR_HAVE_RAMPY) cpp_define (pfile, "__AVR_HAVE_RAMPY__");
|
||||
if (AVR_HAVE_RAMPZ) cpp_define (pfile, "__AVR_HAVE_RAMPZ__");
|
||||
if (AVR_HAVE_ELPM) cpp_define (pfile, "__AVR_HAVE_ELPM__");
|
||||
if (AVR_HAVE_ELPMX) cpp_define (pfile, "__AVR_HAVE_ELPMX__");
|
||||
if (AVR_HAVE_MOVW) cpp_define (pfile, "__AVR_HAVE_MOVW__");
|
||||
if (AVR_HAVE_LPMX) cpp_define (pfile, "__AVR_HAVE_LPMX__");
|
||||
|
||||
if (avr_current_arch->asm_only)
|
||||
cpp_define (pfile, "__AVR_ASM_ONLY__");
|
||||
if (avr_current_arch->have_mul)
|
||||
if (AVR_HAVE_MUL)
|
||||
{
|
||||
cpp_define (pfile, "__AVR_ENHANCED__");
|
||||
cpp_define (pfile, "__AVR_HAVE_MUL__");
|
||||
|
@ -103,6 +101,8 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
|
|||
cpp_define (pfile, "__AVR_MEGA__");
|
||||
cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
|
||||
}
|
||||
if (AVR_XMEGA)
|
||||
cpp_define (pfile, "__AVR_XMEGA__");
|
||||
if (avr_current_arch->have_eijmp_eicall)
|
||||
{
|
||||
cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
|
||||
|
|
|
@ -32,21 +32,27 @@ avr_arch_types[] =
|
|||
/* unknown device specified */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, 1, NULL, "avr2" },
|
||||
/*
|
||||
A M J LM E E E d S S O # F
|
||||
S U M PO L L I a t F ff 6 l
|
||||
M L P MV P P J - - t a R s 4 a
|
||||
XW M M M a r e s
|
||||
X P t t k h */
|
||||
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, 1, "__AVR_ARCH__=1", "avr1" },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, 1, "__AVR_ARCH__=2", "avr2" },
|
||||
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "__AVR_ARCH__=25", "avr25" },
|
||||
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, 1, "__AVR_ARCH__=3", "avr3" },
|
||||
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0x0060, 32, 2, "__AVR_ARCH__=31", "avr31" },
|
||||
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "__AVR_ARCH__=35", "avr35" },
|
||||
{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "__AVR_ARCH__=4", "avr4" },
|
||||
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "__AVR_ARCH__=5", "avr5" },
|
||||
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, 2, "__AVR_ARCH__=51", "avr51" },
|
||||
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, 32, 4, "__AVR_ARCH__=6", "avr6" }
|
||||
A M J LM E E E X R d S S O # F A
|
||||
S U M PO L L I M A a t F ff 6 l r
|
||||
M L P MV P P J E M t a R s 4 a c
|
||||
XW M M M G P a r e s h
|
||||
X P A D t t k h ID */
|
||||
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, 1, "1", "avr1" },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, 1, "2", "avr2" },
|
||||
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "25", "avr25" },
|
||||
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, 1, "3", "avr3" },
|
||||
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0x0060, 32, 2, "31", "avr31" },
|
||||
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "35", "avr35" },
|
||||
{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "4", "avr4" },
|
||||
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, 1, "5", "avr5" },
|
||||
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, 2, "51", "avr51" },
|
||||
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, 32, 4, "6", "avr6" },
|
||||
|
||||
{ 0, 1, 1, 1, 0, 0, 0, 1, 0, 0x2000, 0, 1, "102", "avrxmega2" },
|
||||
{ 0, 1, 1, 1, 0, 0, 0, 1, 0, 0x2000, 0, 1, "104", "avrxmega4" }, /* Same */
|
||||
{ 0, 1, 1, 1, 0, 0, 0, 1, 1, 0x2000, 0, 1, "105", "avrxmega5" },
|
||||
{ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, 4, "106", "avrxmega6" },
|
||||
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0x2000, 0, 4, "107", "avrxmega7" }
|
||||
};
|
||||
|
||||
const struct mcu_type_s avr_mcu_types[] = {
|
||||
|
|
|
@ -201,6 +201,36 @@ AVR_MCU ("at90usb1287", ARCH_AVR51, "__AVR_AT90USB1287__", 0, 0, 0
|
|||
AVR_MCU ("avr6", ARCH_AVR6, NULL, 0, 0, 0x0200, "m2561")
|
||||
AVR_MCU ("atmega2560", ARCH_AVR6, "__AVR_ATmega2560__", 0, 0, 0x0200, "m2560")
|
||||
AVR_MCU ("atmega2561", ARCH_AVR6, "__AVR_ATmega2561__", 0, 0, 0x0200, "m2561")
|
||||
/* Xmega, 16K <= Flash < 64K, RAM <= 64K */
|
||||
AVR_MCU ("avrxmega2", ARCH_AVRXMEGA2, NULL, 0, 0, 0x2000, "x32a4")
|
||||
AVR_MCU ("atxmega16a4", ARCH_AVRXMEGA2, "__AVR_ATxmega16A4__", 0, 0, 0x2000, "x16a4")
|
||||
AVR_MCU ("atxmega16d4", ARCH_AVRXMEGA2, "__AVR_ATxmega16D4__", 0, 0, 0x2000, "x16d4")
|
||||
AVR_MCU ("atxmega16x1", ARCH_AVRXMEGA2, "__AVR_ATxmega16X1__", 0, 0, 0x2000, "x16x1")
|
||||
AVR_MCU ("atxmega32a4", ARCH_AVRXMEGA2, "__AVR_ATxmega32A4__", 0, 0, 0x2000, "x32a4")
|
||||
AVR_MCU ("atxmega32d4", ARCH_AVRXMEGA2, "__AVR_ATxmega32D4__", 0, 0, 0x2000, "x32d4")
|
||||
AVR_MCU ("atxmega32x1", ARCH_AVRXMEGA2, "__AVR_ATxmega32X1__", 0, 0, 0x2000, "x32x1")
|
||||
/* Xmega, Flash == 64K, RAM <= 64K */
|
||||
AVR_MCU ("avrxmega4", ARCH_AVRXMEGA4, NULL, 0, 0, 0x2000, "x64a4")
|
||||
AVR_MCU ("atxmega64a3", ARCH_AVRXMEGA4, "__AVR_ATxmega64A3__", 0, 0, 0x2000, "x64a3")
|
||||
AVR_MCU ("atxmega64d3", ARCH_AVRXMEGA4, "__AVR_ATxmega64D3__", 0, 0, 0x2000, "x64d3")
|
||||
/* Xmega, Flash == 64K, RAM > 64K */
|
||||
AVR_MCU ("avrxmega5", ARCH_AVRXMEGA5, NULL, 0, 0, 0x2000, "x64a1")
|
||||
AVR_MCU ("atxmega64a1", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1__", 0, 0, 0x2000, "x64a1")
|
||||
AVR_MCU ("atxmega64a1u", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1U__", 0, 0, 0x2000, "x64a1u")
|
||||
/* Xmega, 128K <= Flash <= 256K, RAM <= 64K */
|
||||
AVR_MCU ("avrxmega6", ARCH_AVRXMEGA6, NULL, 0, 0, 0x2000, "x128a3")
|
||||
AVR_MCU ("atxmega128a3", ARCH_AVRXMEGA6, "__AVR_ATxmega128A3__", 0, 0, 0x2000, "x128a3")
|
||||
AVR_MCU ("atxmega128d3", ARCH_AVRXMEGA6, "__AVR_ATxmega128D3__", 0, 0, 0x2000, "x128d3")
|
||||
AVR_MCU ("atxmega192a3", ARCH_AVRXMEGA6, "__AVR_ATxmega192A3__", 0, 0, 0x2000, "x192a3")
|
||||
AVR_MCU ("atxmega192d3", ARCH_AVRXMEGA6, "__AVR_ATxmega192D3__", 0, 0, 0x2000, "x192d3")
|
||||
AVR_MCU ("atxmega256a3", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3__", 0, 0, 0x2000, "x256a3")
|
||||
AVR_MCU ("atxmega256a3b", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3B__", 0, 0, 0x2000, "x256a3b")
|
||||
AVR_MCU ("atxmega256a3bu", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3BU__", 0, 0, 0x2000, "x256a3bu")
|
||||
AVR_MCU ("atxmega256d3", ARCH_AVRXMEGA6, "__AVR_ATxmega256D3__", 0, 0, 0x2000, "x256d3")
|
||||
/* Xmega, 128K <= Flash <= 256K, RAM > 64K RAM. */
|
||||
AVR_MCU ("avrxmega7", ARCH_AVRXMEGA7, NULL, 0, 0, 0x2000, "x128a1")
|
||||
AVR_MCU ("atxmega128a1", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1__", 0, 0, 0x2000, "x128a1")
|
||||
AVR_MCU ("atxmega128a1u", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1U__", 0, 0, 0x2000, "x128a1u")
|
||||
/* Assembler only. */
|
||||
AVR_MCU ("avr1", ARCH_AVR1, NULL, 0, 0, 0x0060, "s1200")
|
||||
AVR_MCU ("at90s1200", ARCH_AVR1, "__AVR_AT90S1200__", 0, 0, 0x0060, "s1200")
|
||||
|
|
|
@ -504,20 +504,95 @@ EnumValue
|
|||
Enum(avr_mcu) String(atmega2561) Value(159)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(avr1) Value(160)
|
||||
Enum(avr_mcu) String(avrxmega2) Value(160)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(at90s1200) Value(161)
|
||||
Enum(avr_mcu) String(atxmega16a4) Value(161)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny11) Value(162)
|
||||
Enum(avr_mcu) String(atxmega16d4) Value(162)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny12) Value(163)
|
||||
Enum(avr_mcu) String(atxmega16x1) Value(163)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny15) Value(164)
|
||||
Enum(avr_mcu) String(atxmega32a4) Value(164)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny28) Value(165)
|
||||
Enum(avr_mcu) String(atxmega32d4) Value(165)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega32x1) Value(166)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(avrxmega4) Value(167)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega64a3) Value(168)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega64d3) Value(169)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(avrxmega5) Value(170)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega64a1) Value(171)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega64a1u) Value(172)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(avrxmega6) Value(173)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega128a3) Value(174)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega128d3) Value(175)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega192a3) Value(176)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega192d3) Value(177)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega256a3) Value(178)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega256a3b) Value(179)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega256a3bu) Value(180)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega256d3) Value(181)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(avrxmega7) Value(182)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega128a1) Value(183)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(atxmega128a1u) Value(184)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(avr1) Value(185)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(at90s1200) Value(186)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny11) Value(187)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny12) Value(188)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny15) Value(189)
|
||||
|
||||
EnumValue
|
||||
Enum(avr_mcu) String(attiny28) Value(190)
|
||||
|
||||
|
|
|
@ -112,6 +112,12 @@ typedef struct
|
|||
/* SREG: The pocessor status */
|
||||
int sreg;
|
||||
|
||||
/* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
|
||||
int ccp;
|
||||
int rampd;
|
||||
int rampx;
|
||||
int rampy;
|
||||
|
||||
/* RAMPZ: The high byte of 24-bit address used with ELPM */
|
||||
int rampz;
|
||||
|
||||
|
@ -177,8 +183,18 @@ rtx zero_reg_rtx;
|
|||
extern GTY(()) rtx all_regs_rtx[32];
|
||||
rtx all_regs_rtx[32];
|
||||
|
||||
/* RAMPZ special function register */
|
||||
/* SREG, the processor status */
|
||||
extern GTY(()) rtx sreg_rtx;
|
||||
rtx sreg_rtx;
|
||||
|
||||
/* RAMP* special function registers */
|
||||
extern GTY(()) rtx rampd_rtx;
|
||||
extern GTY(()) rtx rampx_rtx;
|
||||
extern GTY(()) rtx rampy_rtx;
|
||||
extern GTY(()) rtx rampz_rtx;
|
||||
rtx rampd_rtx;
|
||||
rtx rampx_rtx;
|
||||
rtx rampy_rtx;
|
||||
rtx rampz_rtx;
|
||||
|
||||
/* RTX containing the strings "" and "e", respectively */
|
||||
|
@ -424,6 +440,11 @@ avr_option_override (void)
|
|||
/* RAMPZ: Address' high part when loading via ELPM */
|
||||
avr_addr.rampz = 0x3B + avr_current_arch->sfr_offset;
|
||||
|
||||
avr_addr.rampy = 0x3A + avr_current_arch->sfr_offset;
|
||||
avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset;
|
||||
avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset;
|
||||
avr_addr.ccp = 0x34 + avr_current_arch->sfr_offset;
|
||||
|
||||
/* SP: Stack Pointer (SP_H:SP_L) */
|
||||
avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
|
||||
avr_addr.sp_h = avr_addr.sp_l + 1;
|
||||
|
@ -450,13 +471,6 @@ avr_init_expanders (void)
|
|||
{
|
||||
int regno;
|
||||
|
||||
static bool done = false;
|
||||
|
||||
if (done)
|
||||
return;
|
||||
else
|
||||
done = true;
|
||||
|
||||
for (regno = 0; regno < 32; regno ++)
|
||||
all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
|
||||
|
||||
|
@ -466,6 +480,10 @@ avr_init_expanders (void)
|
|||
|
||||
lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
|
||||
|
||||
sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
|
||||
rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
|
||||
rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
|
||||
rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
|
||||
rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
|
||||
|
||||
xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
|
||||
|
@ -903,6 +921,35 @@ emit_push_byte (unsigned regno, bool frame_related_p)
|
|||
cfun->machine->stack_usage++;
|
||||
}
|
||||
|
||||
|
||||
/* Helper for expand_prologue. Emit a push of a SFR via tmp_reg.
|
||||
SFR is a MEM representing the memory location of the SFR.
|
||||
If CLR_P then clear the SFR after the push using zero_reg. */
|
||||
|
||||
static void
|
||||
emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
gcc_assert (MEM_P (sfr));
|
||||
|
||||
/* IN __tmp_reg__, IO(SFR) */
|
||||
insn = emit_move_insn (tmp_reg_rtx, sfr);
|
||||
if (frame_related_p)
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
/* PUSH __tmp_reg__ */
|
||||
emit_push_byte (TMP_REGNO, frame_related_p);
|
||||
|
||||
if (clr_p)
|
||||
{
|
||||
/* OUT IO(SFR), __zero_reg__ */
|
||||
insn = emit_move_insn (sfr, const0_rtx);
|
||||
if (frame_related_p)
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
|
||||
{
|
||||
|
@ -1061,7 +1108,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
|
|||
changed the CFA to the frame pointer this operation
|
||||
need not be annotated if frame pointer is needed. */
|
||||
|
||||
if (AVR_HAVE_8BIT_SP)
|
||||
if (AVR_HAVE_8BIT_SP || AVR_XMEGA)
|
||||
{
|
||||
insn = emit_move_insn (stack_pointer_rtx, fp);
|
||||
}
|
||||
|
@ -1166,26 +1213,42 @@ expand_prologue (void)
|
|||
|
||||
/* Push SREG. */
|
||||
/* ??? There's no dwarf2 column reserved for SREG. */
|
||||
emit_move_insn (tmp_reg_rtx,
|
||||
gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg)));
|
||||
emit_push_byte (TMP_REGNO, false);
|
||||
emit_push_sfr (sreg_rtx, false, false /* clr */);
|
||||
|
||||
/* Push RAMPZ. */
|
||||
/* ??? There's no dwarf2 column reserved for RAMPZ. */
|
||||
if (AVR_HAVE_RAMPZ
|
||||
&& TEST_HARD_REG_BIT (set, REG_Z)
|
||||
&& TEST_HARD_REG_BIT (set, REG_Z + 1))
|
||||
{
|
||||
emit_move_insn (tmp_reg_rtx, rampz_rtx);
|
||||
emit_push_byte (TMP_REGNO, false);
|
||||
}
|
||||
|
||||
/* Clear zero reg. */
|
||||
emit_move_insn (zero_reg_rtx, const0_rtx);
|
||||
|
||||
/* Prevent any attempt to delete the setting of ZERO_REG! */
|
||||
emit_use (zero_reg_rtx);
|
||||
}
|
||||
|
||||
/* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
|
||||
??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */
|
||||
|
||||
if (AVR_HAVE_RAMPD)
|
||||
emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
|
||||
|
||||
if (AVR_HAVE_RAMPX
|
||||
&& TEST_HARD_REG_BIT (set, REG_X)
|
||||
&& TEST_HARD_REG_BIT (set, REG_X + 1))
|
||||
{
|
||||
emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
|
||||
}
|
||||
|
||||
if (AVR_HAVE_RAMPY
|
||||
&& (frame_pointer_needed
|
||||
|| (TEST_HARD_REG_BIT (set, REG_Y)
|
||||
&& TEST_HARD_REG_BIT (set, REG_Y + 1))))
|
||||
{
|
||||
emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
|
||||
}
|
||||
|
||||
if (AVR_HAVE_RAMPZ
|
||||
&& TEST_HARD_REG_BIT (set, REG_Z)
|
||||
&& TEST_HARD_REG_BIT (set, REG_Z + 1))
|
||||
{
|
||||
emit_push_sfr (rampz_rtx, false /* frame-related */, true /* clr */);
|
||||
}
|
||||
} /* is_interrupt is_signal */
|
||||
|
||||
avr_prologue_setup_frame (size, set);
|
||||
|
||||
|
@ -1344,7 +1407,7 @@ expand_epilogue (bool sibcall_p)
|
|||
|
||||
/* Copy to stack pointer. */
|
||||
|
||||
if (AVR_HAVE_8BIT_SP)
|
||||
if (AVR_HAVE_8BIT_SP || AVR_XMEGA)
|
||||
{
|
||||
emit_move_insn (stack_pointer_rtx, fp);
|
||||
}
|
||||
|
@ -1407,9 +1470,27 @@ expand_epilogue (bool sibcall_p)
|
|||
|
||||
if (isr_p)
|
||||
{
|
||||
/* Restore RAMPZ using tmp reg as scratch. */
|
||||
/* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
|
||||
The conditions to restore them must be tha same as in prologue. */
|
||||
|
||||
if (AVR_HAVE_RAMPZ
|
||||
if (AVR_HAVE_RAMPX
|
||||
&& TEST_HARD_REG_BIT (set, REG_X)
|
||||
&& TEST_HARD_REG_BIT (set, REG_X + 1))
|
||||
{
|
||||
emit_pop_byte (TMP_REGNO);
|
||||
emit_move_insn (rampx_rtx, tmp_reg_rtx);
|
||||
}
|
||||
|
||||
if (AVR_HAVE_RAMPY
|
||||
&& (frame_pointer_needed
|
||||
|| (TEST_HARD_REG_BIT (set, REG_Y)
|
||||
&& TEST_HARD_REG_BIT (set, REG_Y + 1))))
|
||||
{
|
||||
emit_pop_byte (TMP_REGNO);
|
||||
emit_move_insn (rampy_rtx, tmp_reg_rtx);
|
||||
}
|
||||
|
||||
if (AVR_HAVE_RAMPZ
|
||||
&& TEST_HARD_REG_BIT (set, REG_Z)
|
||||
&& TEST_HARD_REG_BIT (set, REG_Z + 1))
|
||||
{
|
||||
|
@ -1417,11 +1498,16 @@ expand_epilogue (bool sibcall_p)
|
|||
emit_move_insn (rampz_rtx, tmp_reg_rtx);
|
||||
}
|
||||
|
||||
/* Restore SREG using tmp reg as scratch. */
|
||||
if (AVR_HAVE_RAMPD)
|
||||
{
|
||||
emit_pop_byte (TMP_REGNO);
|
||||
emit_move_insn (rampd_rtx, tmp_reg_rtx);
|
||||
}
|
||||
|
||||
/* Restore SREG using tmp_reg as scratch. */
|
||||
|
||||
emit_pop_byte (TMP_REGNO);
|
||||
emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg)),
|
||||
tmp_reg_rtx);
|
||||
emit_move_insn (sreg_rtx, tmp_reg_rtx);
|
||||
|
||||
/* Restore tmp REG. */
|
||||
emit_pop_byte (TMP_REGNO);
|
||||
|
@ -1903,7 +1989,16 @@ avr_print_operand (FILE *file, rtx x, int code)
|
|||
else if (low_io_address_operand (x, VOIDmode)
|
||||
|| high_io_address_operand (x, VOIDmode))
|
||||
{
|
||||
if (ival == avr_addr.rampz) fprintf (file, "__RAMPZ__");
|
||||
if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
|
||||
fprintf (file, "__RAMPZ__");
|
||||
else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
|
||||
fprintf (file, "__RAMPY__");
|
||||
else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
|
||||
fprintf (file, "__RAMPX__");
|
||||
else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
|
||||
fprintf (file, "__RAMPD__");
|
||||
else if (AVR_XMEGA && ival == avr_addr.ccp)
|
||||
fprintf (file, "__CCP__");
|
||||
else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
|
||||
else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
|
||||
else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__");
|
||||
|
@ -2901,6 +2996,10 @@ output_movhi (rtx insn, rtx xop[], int *plen)
|
|||
{
|
||||
if (AVR_HAVE_8BIT_SP)
|
||||
return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
|
||||
|
||||
if (AVR_XMEGA)
|
||||
return avr_asm_len ("out __SP_L__,%A1" CR_TAB
|
||||
"out __SP_H__,%B1", xop, plen, -2);
|
||||
|
||||
/* Use simple load of SP if no interrupts are used. */
|
||||
|
||||
|
@ -3875,6 +3974,119 @@ out_movqi_mr_r (rtx insn, rtx op[], int *plen)
|
|||
return avr_asm_len ("st %0,%1", op, plen, -1);
|
||||
}
|
||||
|
||||
|
||||
/* Helper for the next function for XMEGA. It does the same
|
||||
but with low byte first. */
|
||||
|
||||
static const char*
|
||||
avr_out_movhi_mr_r_xmega (rtx insn, rtx op[], int *plen)
|
||||
{
|
||||
rtx dest = op[0];
|
||||
rtx src = op[1];
|
||||
rtx base = XEXP (dest, 0);
|
||||
int reg_base = true_regnum (base);
|
||||
int reg_src = true_regnum (src);
|
||||
|
||||
/* "volatile" forces writing low byte first, even if less efficient,
|
||||
for correct operation with 16-bit I/O registers like SP. */
|
||||
int mem_volatile_p = MEM_VOLATILE_P (dest);
|
||||
|
||||
if (CONSTANT_ADDRESS_P (base))
|
||||
return optimize > 0 && io_address_operand (base, HImode)
|
||||
? avr_asm_len ("out %i0,%A1" CR_TAB
|
||||
"out %i0+1,%B1", op, plen, -2)
|
||||
|
||||
: avr_asm_len ("sts %m0,%A1" CR_TAB
|
||||
"sts %m0+1,%B1", op, plen, -4);
|
||||
|
||||
if (reg_base > 0)
|
||||
{
|
||||
if (reg_base != REG_X)
|
||||
return avr_asm_len ("st %0,%A1" CR_TAB
|
||||
"std %0+1,%B1", op, plen, -2);
|
||||
|
||||
if (reg_src == REG_X)
|
||||
/* "st X+,r26" and "st -X,r26" are undefined. */
|
||||
avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
|
||||
"st X,r26" CR_TAB
|
||||
"adiw r26,1" CR_TAB
|
||||
"st X,__tmp_reg__", op, plen, -4);
|
||||
else
|
||||
avr_asm_len ("st X+,%A1" CR_TAB
|
||||
"st X,%B1", op, plen, -2);
|
||||
|
||||
return reg_unused_after (insn, src)
|
||||
? ""
|
||||
: avr_asm_len ("sbiw r26,1", op, plen, 1);
|
||||
}
|
||||
else if (GET_CODE (base) == PLUS)
|
||||
{
|
||||
int disp = INTVAL (XEXP (base, 1));
|
||||
reg_base = REGNO (XEXP (base, 0));
|
||||
if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
|
||||
{
|
||||
if (reg_base != REG_Y)
|
||||
fatal_insn ("incorrect insn:",insn);
|
||||
|
||||
return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
|
||||
? avr_asm_len ("adiw r28,%o0-62" CR_TAB
|
||||
"std Y+62,%A1" CR_TAB
|
||||
"std Y+63,%B1" CR_TAB
|
||||
"sbiw r28,%o0-62", op, plen, -4)
|
||||
|
||||
: avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
|
||||
"sbci r29,hi8(-%o0)" CR_TAB
|
||||
"st Y,%A1" CR_TAB
|
||||
"std Y+1,%B1" CR_TAB
|
||||
"subi r28,lo8(%o0)" CR_TAB
|
||||
"sbci r29,hi8(%o0)", op, plen, -6);
|
||||
}
|
||||
|
||||
if (reg_base != REG_X)
|
||||
return avr_asm_len ("std %A0,%A1" CR_TAB
|
||||
"std %B0,%B1", op, plen, -2);
|
||||
/* (X + d) = R */
|
||||
return reg_src == REG_X
|
||||
? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
|
||||
"mov __zero_reg__,r27" CR_TAB
|
||||
"adiw r26,%o0" CR_TAB
|
||||
"st X+,__tmp_reg__" CR_TAB
|
||||
"st X,__zero_reg__" CR_TAB
|
||||
"clr __zero_reg__" CR_TAB
|
||||
"sbiw r26,%o0+1", op, plen, -7)
|
||||
|
||||
: avr_asm_len ("adiw r26,%o0" CR_TAB
|
||||
"st X+,%A1" CR_TAB
|
||||
"st X,%B1" CR_TAB
|
||||
"sbiw r26,%o0+1", op, plen, -4);
|
||||
}
|
||||
else if (GET_CODE (base) == PRE_DEC) /* (--R) */
|
||||
{
|
||||
if (!mem_volatile_p)
|
||||
return avr_asm_len ("st %0,%B1" CR_TAB
|
||||
"st %0,%A1", op, plen, -2);
|
||||
|
||||
return REGNO (XEXP (base, 0)) == REG_X
|
||||
? avr_asm_len ("sbiw r26,2" CR_TAB
|
||||
"st X+,%A1" CR_TAB
|
||||
"st X,%B1" CR_TAB
|
||||
"sbiw r26,1", op, plen, -4)
|
||||
|
||||
: avr_asm_len ("sbiw %r0,2" CR_TAB
|
||||
"st %p0,%A1" CR_TAB
|
||||
"std %p0+1,%B1", op, plen, -3);
|
||||
}
|
||||
else if (GET_CODE (base) == POST_INC) /* (R++) */
|
||||
{
|
||||
return avr_asm_len ("st %0,%A1" CR_TAB
|
||||
"st %0,%B1", op, plen, -2);
|
||||
|
||||
}
|
||||
fatal_insn ("unknown move insn:",insn);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
out_movhi_mr_r (rtx insn, rtx op[], int *plen)
|
||||
{
|
||||
|
@ -3883,9 +4095,16 @@ out_movhi_mr_r (rtx insn, rtx op[], int *plen)
|
|||
rtx base = XEXP (dest, 0);
|
||||
int reg_base = true_regnum (base);
|
||||
int reg_src = true_regnum (src);
|
||||
/* "volatile" forces writing high byte first, even if less efficient,
|
||||
for correct operation with 16-bit I/O registers. */
|
||||
int mem_volatile_p = MEM_VOLATILE_P (dest);
|
||||
int mem_volatile_p;
|
||||
|
||||
/* "volatile" forces writing high-byte first (no-xmega) resp.
|
||||
low-byte first (xmega) even if less efficient, for correct
|
||||
operation with 16-bit I/O registers like. */
|
||||
|
||||
if (AVR_XMEGA)
|
||||
return avr_out_movhi_mr_r_xmega (insn, op, plen);
|
||||
|
||||
mem_volatile_p = MEM_VOLATILE_P (dest);
|
||||
|
||||
if (CONSTANT_ADDRESS_P (base))
|
||||
return optimize > 0 && io_address_operand (base, HImode)
|
||||
|
@ -7332,7 +7551,16 @@ avr_file_start (void)
|
|||
|
||||
fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
|
||||
fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
|
||||
fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
|
||||
if (AVR_HAVE_RAMPZ)
|
||||
fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
|
||||
if (AVR_HAVE_RAMPY)
|
||||
fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
|
||||
if (AVR_HAVE_RAMPX)
|
||||
fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
|
||||
if (AVR_HAVE_RAMPD)
|
||||
fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
|
||||
if (AVR_XMEGA)
|
||||
fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
|
||||
fprintf (asm_out_file, "__tmp_reg__ = %d\n", TMP_REGNO);
|
||||
fprintf (asm_out_file, "__zero_reg__ = %d\n", ZERO_REGNO);
|
||||
}
|
||||
|
|
|
@ -46,11 +46,12 @@ struct base_arch_s
|
|||
/* Core have 'EICALL' and 'EIJMP' instructions. */
|
||||
int have_eijmp_eicall;
|
||||
|
||||
/* Reserved for xmega architecture. */
|
||||
int reserved;
|
||||
/* This is an XMEGA core. */
|
||||
int xmega_p;
|
||||
|
||||
/* Reserved for xmega architecture. */
|
||||
int reserved2;
|
||||
/* This core has the RAMPD special function register
|
||||
and thus also the RAMPX, RAMPY and RAMPZ registers. */
|
||||
int have_rampd;
|
||||
|
||||
/* Default start of data section address for architecture. */
|
||||
int default_data_section_start;
|
||||
|
@ -62,6 +63,7 @@ struct base_arch_s
|
|||
/* Number of 64k segments in the flash. */
|
||||
int n_segments;
|
||||
|
||||
/* Architecture id to built-in define __AVR_ARCH__ (NULL -> no macro) */
|
||||
const char *const macro;
|
||||
|
||||
/* Architecture name. */
|
||||
|
@ -83,7 +85,12 @@ enum avr_arch
|
|||
ARCH_AVR4,
|
||||
ARCH_AVR5,
|
||||
ARCH_AVR51,
|
||||
ARCH_AVR6
|
||||
ARCH_AVR6,
|
||||
ARCH_AVRXMEGA2,
|
||||
ARCH_AVRXMEGA4,
|
||||
ARCH_AVRXMEGA5,
|
||||
ARCH_AVRXMEGA6,
|
||||
ARCH_AVRXMEGA7
|
||||
};
|
||||
|
||||
struct mcu_type_s {
|
||||
|
@ -175,13 +182,19 @@ enum
|
|||
#define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx)
|
||||
#define AVR_HAVE_ELPM (avr_current_arch->have_elpm)
|
||||
#define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx)
|
||||
#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm)
|
||||
#define AVR_HAVE_RAMPD (avr_current_arch->have_rampd)
|
||||
#define AVR_HAVE_RAMPX (avr_current_arch->have_rampd)
|
||||
#define AVR_HAVE_RAMPY (avr_current_arch->have_rampd)
|
||||
#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm \
|
||||
|| avr_current_arch->have_rampd)
|
||||
#define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
|
||||
#define AVR_HAVE_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK)
|
||||
|
||||
#define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL)
|
||||
#define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
|
||||
|
||||
#define AVR_XMEGA (avr_current_arch->xmega_p)
|
||||
|
||||
#define BITS_BIG_ENDIAN 0
|
||||
#define BYTES_BIG_ENDIAN 0
|
||||
#define WORDS_BIG_ENDIAN 0
|
||||
|
|
|
@ -155,9 +155,10 @@
|
|||
;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
|
||||
;; lpm : ISA has no LPMX lpmx : ISA has LPMX
|
||||
;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
|
||||
;; no_xmega: non-XMEGA core xmega : XMEGA core
|
||||
|
||||
(define_attr "isa"
|
||||
"mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx,
|
||||
"mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
|
||||
standard"
|
||||
(const_string "standard"))
|
||||
|
||||
|
@ -204,6 +205,14 @@
|
|||
(and (eq_attr "isa" "elpmx")
|
||||
(match_test "AVR_HAVE_ELPMX"))
|
||||
(const_int 1)
|
||||
|
||||
(and (eq_attr "isa" "xmega")
|
||||
(match_test "AVR_XMEGA"))
|
||||
(const_int 1)
|
||||
|
||||
(and (eq_attr "isa" "no_xmega")
|
||||
(match_test "!AVR_XMEGA"))
|
||||
(const_int 1)
|
||||
] (const_int 0)))
|
||||
|
||||
|
||||
|
@ -580,15 +589,17 @@
|
|||
;; handled by generic movhi insn.
|
||||
|
||||
(define_insn "movhi_sp_r"
|
||||
[(set (match_operand:HI 0 "stack_register_operand" "=q,q")
|
||||
(unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r")
|
||||
(match_operand:HI 2 "const_int_operand" "L,P")]
|
||||
[(set (match_operand:HI 0 "stack_register_operand" "=q,q,q")
|
||||
(unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r")
|
||||
(match_operand:HI 2 "const_int_operand" "L,P,LP")]
|
||||
UNSPECV_WRITE_SP))]
|
||||
"!AVR_HAVE_8BIT_SP"
|
||||
"@
|
||||
out __SP_H__,%B1\;out __SP_L__,%A1
|
||||
cli\;out __SP_H__,%B1\;sei\;out __SP_L__,%A1"
|
||||
[(set_attr "length" "2,4")
|
||||
cli\;out __SP_H__,%B1\;sei\;out __SP_L__,%A1
|
||||
out __SP_L__,%A1\;out __SP_H__,%B1"
|
||||
[(set_attr "length" "2,4,2")
|
||||
(set_attr "isa" "no_xmega,no_xmega,xmega")
|
||||
(set_attr "cc" "none")])
|
||||
|
||||
(define_peephole2
|
||||
|
|
|
@ -44,19 +44,24 @@ static const char* const avr_multilib_raw[] = {
|
|||
"avr25/tiny-stack mmcu=attiny261;",
|
||||
"avr25/tiny-stack mmcu=attiny261a;",
|
||||
|
||||
". !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mtiny-stack !mmcu=at90s2313 !mmcu=at90s2323 !mmcu=at90s2333 !mmcu=at90s2343 !mmcu=attiny22 !mmcu=attiny26 !mmcu=at90s4433 !mmcu=attiny13 !mmcu=attiny13a !mmcu=attiny2313 !mmcu=attiny2313a !mmcu=attiny24 !mmcu=attiny24a !mmcu=attiny25 !mmcu=attiny261 !mmcu=attiny261a;",
|
||||
"avr2 mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mtiny-stack;",
|
||||
"avr25 !mmcu=avr2 mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mtiny-stack;",
|
||||
"avr3 !mmcu=avr2 !mmcu=avr25 mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6;",
|
||||
"avr31 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6;",
|
||||
"avr35 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6;",
|
||||
"avr4 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6;",
|
||||
"avr5 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 mmcu=avr5 !mmcu=avr51 !mmcu=avr6;",
|
||||
"avr51 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 mmcu=avr51 !mmcu=avr6;",
|
||||
"avr6 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 mmcu=avr6;",
|
||||
"tiny-stack !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 mtiny-stack;",
|
||||
"avr2/tiny-stack mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 mtiny-stack;",
|
||||
"avr25/tiny-stack !mmcu=avr2 mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 mtiny-stack;",
|
||||
". !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 !mtiny-stack !mmcu=at90s2313 !mmcu=at90s2323 !mmcu=at90s2333 !mmcu=at90s2343 !mmcu=attiny22 !mmcu=attiny26 !mmcu=at90s4433 !mmcu=attiny13 !mmcu=attiny13a !mmcu=attiny2313 !mmcu=attiny2313a !mmcu=attiny24 !mmcu=attiny24a !mmcu=attiny25 !mmcu=attiny261 !mmcu=attiny261a;",
|
||||
"avr2 mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 !mtiny-stack;",
|
||||
"avr25 !mmcu=avr2 mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 !mtiny-stack;",
|
||||
"avr3 !mmcu=avr2 !mmcu=avr25 mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avr31 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avr35 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avr4 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avr5 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avr51 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avr6 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avrxmega2 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avrxmega4 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avrxmega5 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avrxmega6 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 mmcu=avrxmega6 !mmcu=avrxmega7;",
|
||||
"avrxmega7 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 mmcu=avrxmega7;",
|
||||
"tiny-stack !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 mtiny-stack;",
|
||||
"avr2/tiny-stack mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 mtiny-stack;",
|
||||
"avr25/tiny-stack !mmcu=avr2 mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 mtiny-stack;",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -45,17 +45,20 @@
|
|||
;; Return true if OP is a valid address for lower half of I/O space.
|
||||
(define_predicate "low_io_address_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IN_RANGE((INTVAL (op)), 0x20, 0x3F)")))
|
||||
(match_test "IN_RANGE (INTVAL (op) - avr_current_arch->sfr_offset,
|
||||
0, 0x1f)")))
|
||||
|
||||
;; Return true if OP is a valid address for high half of I/O space.
|
||||
(define_predicate "high_io_address_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IN_RANGE((INTVAL (op)), 0x40, 0x5F)")))
|
||||
(match_test "IN_RANGE (INTVAL (op) - avr_current_arch->sfr_offset,
|
||||
0x20, 0x3F)")))
|
||||
|
||||
;; Return true if OP is a valid address of I/O space.
|
||||
(define_predicate "io_address_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IN_RANGE((INTVAL (op)), 0x20, (0x60 - GET_MODE_SIZE(mode)))")))
|
||||
(match_test "IN_RANGE (INTVAL (op) - avr_current_arch->sfr_offset,
|
||||
0, 0x40 - GET_MODE_SIZE (mode))")))
|
||||
|
||||
;; Return 1 if OP is a general operand not in flash memory
|
||||
(define_predicate "nop_general_operand"
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6 mtiny-stack
|
||||
MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 mtiny-stack
|
||||
|
||||
MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 tiny-stack avr25/tiny-stack
|
||||
MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack avr25/tiny-stack
|
||||
|
||||
MULTILIB_EXCEPTIONS = \
|
||||
mmcu=avr3/mtiny-stack \
|
||||
|
@ -32,7 +32,12 @@ MULTILIB_EXCEPTIONS = \
|
|||
mmcu=avr4/mtiny-stack \
|
||||
mmcu=avr5/mtiny-stack \
|
||||
mmcu=avr51/mtiny-stack \
|
||||
mmcu=avr6/mtiny-stack
|
||||
mmcu=avr6/mtiny-stack \
|
||||
mmcu=avrxmega2/mtiny-stack \
|
||||
mmcu=avrxmega4/mtiny-stack \
|
||||
mmcu=avrxmega5/mtiny-stack \
|
||||
mmcu=avrxmega6/mtiny-stack \
|
||||
mmcu=avrxmega7/mtiny-stack
|
||||
|
||||
MULTILIB_MATCHES = \
|
||||
mmcu?at90s2313=mmcu?at90s2313 \
|
||||
|
@ -189,4 +194,24 @@ MULTILIB_MATCHES = \
|
|||
mmcu?avr51=mmcu?at90usb1286 \
|
||||
mmcu?avr51=mmcu?at90usb1287 \
|
||||
mmcu?avr6=mmcu?atmega2560 \
|
||||
mmcu?avr6=mmcu?atmega2561
|
||||
mmcu?avr6=mmcu?atmega2561 \
|
||||
mmcu?avrxmega2=mmcu?atxmega16a4 \
|
||||
mmcu?avrxmega2=mmcu?atxmega16d4 \
|
||||
mmcu?avrxmega2=mmcu?atxmega16x1 \
|
||||
mmcu?avrxmega2=mmcu?atxmega32a4 \
|
||||
mmcu?avrxmega2=mmcu?atxmega32d4 \
|
||||
mmcu?avrxmega2=mmcu?atxmega32x1 \
|
||||
mmcu?avrxmega4=mmcu?atxmega64a3 \
|
||||
mmcu?avrxmega4=mmcu?atxmega64d3 \
|
||||
mmcu?avrxmega5=mmcu?atxmega64a1 \
|
||||
mmcu?avrxmega5=mmcu?atxmega64a1u \
|
||||
mmcu?avrxmega6=mmcu?atxmega128a3 \
|
||||
mmcu?avrxmega6=mmcu?atxmega128d3 \
|
||||
mmcu?avrxmega6=mmcu?atxmega192a3 \
|
||||
mmcu?avrxmega6=mmcu?atxmega192d3 \
|
||||
mmcu?avrxmega6=mmcu?atxmega256a3 \
|
||||
mmcu?avrxmega6=mmcu?atxmega256a3b \
|
||||
mmcu?avrxmega6=mmcu?atxmega256a3bu \
|
||||
mmcu?avrxmega6=mmcu?atxmega256d3 \
|
||||
mmcu?avrxmega7=mmcu?atxmega128a1 \
|
||||
mmcu?avrxmega7=mmcu?atxmega128a1u
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2012-01-15 Georg-Johann Lay <avr@gjlay.de>
|
||||
Anatoly Sokolov <aesok@post.ru>
|
||||
Eric Weddington <eric.weddington@atmel.com>
|
||||
|
||||
PR target/52261
|
||||
* config/avr/lib1funcs.S (__prologue_saves__): Handle AVR_XMEGA
|
||||
(__epilogue_restores__): Ditto.
|
||||
|
||||
2012-02-15 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR target/51921
|
||||
|
|
|
@ -1696,6 +1696,13 @@ DEFUN __prologue_saves__
|
|||
sub r28,r26
|
||||
out __SP_L__,r28
|
||||
clr r29
|
||||
#elif defined (__AVR__XMEGA__)
|
||||
in r28,__SP_L__
|
||||
in r29,__SP_H__
|
||||
sub r28,r26
|
||||
sbc r29,r27
|
||||
out __SP_L__,r28
|
||||
out __SP_H__,r29
|
||||
#else
|
||||
in r28,__SP_L__
|
||||
in r29,__SP_H__
|
||||
|
@ -1745,6 +1752,13 @@ DEFUN __epilogue_restores__
|
|||
add r28,r30
|
||||
out __SP_L__,r28
|
||||
mov r28, r26
|
||||
#elif defined (__AVR__XMEGA__)
|
||||
ldd r27,Y+1
|
||||
add r28,r30
|
||||
adc r29,__zero_reg__
|
||||
out __SP_L__,r28
|
||||
out __SP_H__,r29
|
||||
wmov 28, 26
|
||||
#else
|
||||
ldd r27,Y+1
|
||||
add r28,r30
|
||||
|
|
Loading…
Add table
Reference in a new issue