diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c index d382fd987d..5049d11b9d 100644 --- a/gas/config/tc-avr.c +++ b/gas/config/tc-avr.c @@ -326,8 +326,10 @@ static struct mcu_type_s mcu_types[] = {NULL, 0, 0} }; + /* Current MCU type. */ static struct mcu_type_s default_mcu = {"avr2", AVR_ISA_AVR2, bfd_mach_avr2}; +static struct mcu_type_s specified_mcu; static struct mcu_type_s * avr_mcu = & default_mcu; /* AVR target-specific switches. */ @@ -398,7 +400,8 @@ enum options { OPTION_ALL_OPCODES = OPTION_MD_BASE + 1, OPTION_NO_SKIP_BUG, - OPTION_NO_WRAP + OPTION_NO_WRAP, + OPTION_ISA_RMW }; struct option md_longopts[] = @@ -407,6 +410,7 @@ struct option md_longopts[] = { "mall-opcodes", no_argument, NULL, OPTION_ALL_OPCODES }, { "mno-skip-bug", no_argument, NULL, OPTION_NO_SKIP_BUG }, { "mno-wrap", no_argument, NULL, OPTION_NO_WRAP }, + { "mrmw", no_argument, NULL, OPTION_ISA_RMW }, { NULL, no_argument, NULL, 0 } }; @@ -511,7 +515,9 @@ md_show_usage (FILE *stream) " -mno-skip-bug disable warnings for skipping two-word instructions\n" " (default for avr4, avr5)\n" " -mno-wrap reject rjmp/rcall instructions with 8K wrap-around\n" - " (default for avr3, avr5)\n")); + " (default for avr3, avr5)\n" + " -mrmw accept Read-Modify-Write instructions\n" + )); show_mcu_list (stream); } @@ -558,7 +564,12 @@ md_parse_option (int c, char *arg) type - this for allows passing -mmcu=... via gcc ASM_SPEC as well as .arch ... in the asm output at the same time. */ if (avr_mcu == &default_mcu || avr_mcu->mach == mcu_types[i].mach) - avr_mcu = &mcu_types[i]; + { + specified_mcu.name = mcu_types[i].name; + specified_mcu.isa |= mcu_types[i].isa; + specified_mcu.mach = mcu_types[i].mach; + avr_mcu = &specified_mcu; + } else as_fatal (_("redefinition of mcu type `%s' to `%s'"), avr_mcu->name, mcu_types[i].name); @@ -573,6 +584,9 @@ md_parse_option (int c, char *arg) case OPTION_NO_WRAP: avr_opt.no_wrap = 1; return 1; + case OPTION_ISA_RMW: + specified_mcu.isa |= AVR_ISA_RMW; + return 1; } return 0; diff --git a/gas/doc/c-avr.texi b/gas/doc/c-avr.texi index e9cc2743f7..305e64cf30 100644 --- a/gas/doc/c-avr.texi +++ b/gas/doc/c-avr.texi @@ -129,6 +129,10 @@ This option disable warnings for skipping two-word instructions. @item -mno-wrap This option reject @code{rjmp/rcall} instructions with 8K wrap-around. +@cindex @code{-mrmw} command line option, AVR +@item -mrmw +Accept Read-Modify-Write (@code{XCH,LAC,LAS,LAT}) instructions. + @end table diff --git a/gas/testsuite/gas/avr/avr.exp b/gas/testsuite/gas/avr/avr.exp new file mode 100644 index 0000000000..fc90f9f64b --- /dev/null +++ b/gas/testsuite/gas/avr/avr.exp @@ -0,0 +1,24 @@ +# Copyright 2014 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +# +# Some AVR tests +# + +if {[istarget avr-*-*]} { + run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]] +} diff --git a/gas/testsuite/gas/avr/rmw.d b/gas/testsuite/gas/avr/rmw.d new file mode 100644 index 0000000000..48554e15bf --- /dev/null +++ b/gas/testsuite/gas/avr/rmw.d @@ -0,0 +1,23 @@ +#name: AVR RMW instructions +#as: -mmcu=avrxmega2 -mrmw +#objdump: -dr --show-raw-insn +#target: avr-*-* + +.*: +file format elf32-avr + +Disassembly of section .text: + +00000000
: + 0: cf 93 push r28 + 2: df 93 push r29 + 4: cd b7 in r28, 0x3d ; 61 + 6: de b7 in r29, 0x3e ; 62 + 8: c4 92 xch Z, r12 + a: c5 92 las Z, r12 + c: c6 92 lac Z, r12 + e: c7 92 lat Z, r12 + 10: 80 e0 ldi r24, 0x00 ; 0 + 12: 90 e0 ldi r25, 0x00 ; 0 + 14: df 91 pop r29 + 16: cf 91 pop r28 + 18: 08 95 ret diff --git a/gas/testsuite/gas/avr/rmw.s b/gas/testsuite/gas/avr/rmw.s new file mode 100644 index 0000000000..fca39c9e8b --- /dev/null +++ b/gas/testsuite/gas/avr/rmw.s @@ -0,0 +1,32 @@ + .file "rmw.s" +__SP_H__ = 0x3e +__SP_L__ = 0x3d +__SREG__ = 0x3f +__CCP__ = 0x34 +__tmp_reg__ = 0 +__zero_reg__ = 1 + .text +.global main + .type main, @function +main: + push r28 + push r29 + in r28,__SP_L__ + in r29,__SP_H__ +/* prologue: function */ +/* frame size = 0 */ +/* stack size = 2 */ +.L__stack_usage = 2 +/* #APP */ + xch Z, r12 + las Z, r12 + lac Z, r12 + lat Z, r12 +/* #NOAPP */ + ldi r24,0 + ldi r25,0 +/* epilogue start */ + pop r29 + pop r28 + ret + .size main, .-main