From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26962 invoked by alias); 25 Jul 2014 13:16:00 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 26936 invoked by uid 89); 25 Jul 2014 13:15:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=2.6 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_NONE,UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: smtp.centurylink.net Received: from mail.centurylink.net (HELO smtp.centurylink.net) (205.219.233.9) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 25 Jul 2014 13:15:33 +0000 X_CMAE_Category: , , X-CNFS-Analysis: v=2.0 cv=ffovOjsF c=1 sm=1 a=kranDmSTaCk61G2o8f10jA==:17 a=oBghVyC96rYA:10 a=yMB-mh8mtQkA:10 a=x1JHTF3VILYA:10 a=IkcTkHD0fZMA:10 a=yrnTiy7_AAAA:8 a=FP58Ms26AAAA:8 a=mDV3o1hIAAAA:8 a=s8aHb4BRY5oWDMaxlVwA:9 a=QEXdDO2ut3YA:10 a=DvHBMr9IpwMA:10 a=MUgysaN147qXDTTB:21 a=LYSGWI4_ictWANdm:21 a=kranDmSTaCk61G2o8f10jA==:117 X-CM-Score: 0 X-Authed-Username: eWF0ZXNmcmVlZGFyYW5keUBjZW50dXJ5bGluay5uZXQ= Authentication-Results: smtp02.agate.dfw.synacor.com header.from=yates@digitalsignallabs.com; sender-id=neutral Authentication-Results: smtp02.agate.dfw.synacor.com smtp.mail=yates@digitalsignallabs.com; spf=neutral; sender-id=neutral Authentication-Results: smtp02.agate.dfw.synacor.com smtp.user=yatesfreedarandy@centurylink.net; auth=pass (LOGIN) Received-SPF: neutral (smtp02.agate.dfw.synacor.com: 67.232.27.161 is neither permitted nor denied by domain of digitalsignallabs.com) Received: from [67.232.27.161] ([67.232.27.161:59128] helo=galois.digitalsignallabs.com) by smtp.centurylink.net (envelope-from ) (ecelerity 3.5.1.37854 r(Momo-dev:3.5.1.0)) with ESMTPA id 6A/9C-23169-E6852D35; Fri, 25 Jul 2014 09:15:30 -0400 Received: from localhost.localdomain (nc-67-232-27-161.dhcp.embarqhsd.net [67.232.27.161]) by galois.digitalsignallabs.com (Postfix) with ESMTPA id 594EDE0CC5 for ; Fri, 25 Jul 2014 09:15:25 -0400 (EDT) From: Randy Yates To: binutils@sourceware.org Subject: Re: Building binutils for mspgcc fails References: <87ppgzs8qh.fsf@digitalsignallabs.com> Date: Fri, 25 Jul 2014 13:16:00 -0000 In-Reply-To: <87ppgzs8qh.fsf@digitalsignallabs.com> (Randy Yates's message of "Sun, 20 Jul 2014 23:15:18 -0400") Message-ID: <877g31shuv.fsf@digitalsignallabs.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2014-07/txt/msg00197.txt.bz2 Does anyone have any suggestions on this error? --Randy Randy Yates writes: > I'm attempting to build binutils for the msp430. I am following > the instructions in the mspgcc-20120406 project, namely in the > patch file shown at the end of this message.=20 > > Everything goes fine until I hit the build step, at which point > I get this error: > > ... > config.status: executing default commands > make[2]: Entering directory `/home/ess-tool/package/mspgcc/binutils/BUILD= /binutils/libiberty' > if [ x"" !=3D x ] && [ ! -d pic ]; then \ > mkdir pic; \ > else true; fi > touch stamp-picdir > if [ x"" !=3D x ]; then \ > gcc -c -DHAVE_CONFIG_H -g -O2 -I. -I../../../binutils-2.21.1/libiberty= /../include -W -Wall -Wwrite-strings -Wc++-compat -Wstrict-prototypes -ped= antic ../../../binutils-2.21.1/libiberty/regex.c -o pic/regex.o; \ > else true; fi > gcc -c -DHAVE_CONFIG_H -g -O2 -I. -I../../../binutils-2.21.1/libiberty/.= ./include -W -Wall -Wwrite-strings -Wc++-compat -Wstrict-prototypes -pedan= tic ../../../binutils-2.21.1/libiberty/regex.c -o regex.o > /tmp/ccup7V3n.s: Assembler messages: > /tmp/ccup7V3n.s:119: Error: expecting string instruction after `rep' > make[2]: *** [regex.o] Error 1 > make[2]: Leaving directory `/home/ess-tool/package/mspgcc/binutils/BUILD/= binutils/libiberty' > make[1]: *** [all-libiberty] Error 2 > make[1]: Leaving directory `/home/ess-tool/package/mspgcc/binutils/BUILD/= binutils' > make: *** [all] Error 2 > > Any help would be appreciated. > > --Randy > > > > > > > > ----begin msp430-binutils-2.21.1a-20120406.patch---- > > Copyright 2000-2012 Free Software Foundation, Inc. > > The material in this patch is a derivative work of the binutils package, > and is subject to licensing and copyright of its parent package. > > This patch adds/enhances support for the Texas Instruments MSP430 family = of > microcontrollers to GNU binutils. The material incorporated is maintained > in a git repository hosted at: > > git://mspgcc.git.sourceforge.net/gitroot/mspgcc/binutils > > This patch incorporates changes between: > upstream/release/binutils-2.21.1a (0fa867528e69dea548c480b010ce6e57f025= 2d88) > and > binutils-2_21/binutils-2.21.1a (a4bb260d153bf595a1960ad6b3f6b9524a3ea52= f) > > To build, obtain the upstream release distribution from: > ftp://ftp.gnu.org/pub/gnu/binutils/binutils-2.21.1a.tar.bz2 > > Unpack the distribution, apply the patch, and build. (Note: The example > commands are in Bourne-shell syntax.) > > tar xjf binutils-2.21.1a.tar.bz2 > ( cd binutils-2.21.1 ; patch -p1 < ../msp430-binutils-2.21.1a-20120406.= patch ) > mkdir -p BUILD/binutils > cd BUILD/binutils > ../../binutils-2.21.1/configure \ > --target=3Dmsp430 \ > --prefix=3D/usr/local/msp430 \ > 2>&1 | tee co > make 2>&1 | tee mo > make install 2>&1 | tee moi > > For support please use the mspgcc-users mailing list. You can subscribe = at > https://lists.sourceforge.net/lists/listinfo/mspgcc-users. Once subscrib= ed, > you can post by email to mspgcc-users@lists.sourceforge.net. To report > bugs, please file a tracker ticket on SourceForge at > https://sourceforge.net/tracker/?group_id=3D42303&atid=3D432701 > > Log of relevant changes: > 5c6c3c5 [2012-04-06 08:28:15 -0500] Update DEV-PHASE for release > fb6b35b [2012-03-29 04:00:07 -0500] SF 3512502 address mode fails to acce= pt CG-compatible immediates > b8f22db [2012-03-30 18:53:47 -0500] Update DEV-PHASE for release > 8792f21 [2012-02-24 14:34:37 -0600] Update DEV-PHASE for release > 34e6e3e [2012-02-23 12:26:43 -0600] Use standard DOLLAR_DOT approach inst= ead of custom version > 40427a9 [2012-02-21 10:15:55 -0600] Cleanup detection of pc-relative fixu= p/relocations > a45799e [2012-02-21 07:36:30 -0600] SF 3489407 restore legacy symbolic op= erands > b68626d [2012-02-19 15:03:46 -0600] Baby-step cleanup > 7d349a6 [2012-02-19 12:22:50 -0600] Eliminate constraints preventing symb= ol-.(r0) or symbol(r2) > 103affc [2012-02-19 11:08:27 -0600] Make dependence on r0 explicit when e= mitting indexed operands > bc03deb [2012-02-18 10:29:14 -0600] Refactor code that emits fixups > 0262728 [2012-02-18 09:16:32 -0600] Default to non-PC-relative symbolic r= elocations > 85ed849 [2012-02-17 19:25:11 -0600] Default to non-PC-relative conditiona= l jump relocations > 09a1693 [2012-02-17 18:34:28 -0600] Add non-PCREL 10-bit conditional jump= relocation > 88441f7 [2012-02-17 18:14:44 -0600] cleanup fixup application > 00d0a26 [2012-02-17 13:43:27 -0600] SF 3488636 mis-assembly using program= location counter > 5662d49 [2012-02-17 10:11:57 -0600] SF 3487856 gas mis-disassemble symbol= ics > 62a820f [2012-02-17 04:39:16 -0600] msp430-dis: clean up magic numbers > 789f569 [2012-02-17 03:27:30 -0600] emit more useful error when addresses= unaligned > 935c689 [2012-02-17 02:34:01 -0600] Run code through indent again > 189821e [2012-02-16 19:51:42 -0600] Validate relocation ranges > dcf90bd [2012-02-16 15:56:45 -0600] Enhance range validation in assembler > 94928fe [2012-02-15 20:32:48 -0600] Document all relocations > d8b1461 [2012-02-15 20:30:48 -0600] Clean up fixup formatting/fallthru > 296d3e6 [2012-02-15 19:55:29 -0600] Correct and validate HOWTO order > 9cf1fb7 [2012-02-15 18:46:58 -0600] Refactor reloc selection and storage > 95aad4b [2012-02-15 16:04:46 -0600] Remove unnecessary imm_op output para= meter > 9157313 [2012-02-15 15:53:10 -0600] Relax operand alignment check for pus= h/pushx > bc104f9 [2012-02-15 13:42:50 -0600] Disallow unaligned access off stack p= ointer > d1a8e41 [2012-02-15 13:37:23 -0600] Uniform detection of encoded immediat= es that might break alignment > 2fa9206 [2012-02-15 08:00:32 -0600] Avoid gratuitous distinction between = source/dest addressing modes > 35b9a77 [2012-02-15 07:08:46 -0600] Eliminate redundant mode field > 5155840 [2012-02-15 02:44:16 -0600] Move all dwarf2 line emission to end = of function. > c0f1b8f [2012-02-14 20:43:24 -0600] Fix error due to inconsistent use of = __is > af2a99f [2012-02-14 20:38:03 -0600] Revert effect of 3487332 and 3487629 > 1dfe5ba [2012-02-14 19:56:18 -0600] Rename local variable for clarity > 23ecf6b [2012-02-14 16:59:25 -0600] Remove redundant set of op->mode > 67a0783 [2012-02-14 13:27:56 -0600] Catch unhandled unsupported operands > 5b51a1d [2012-02-14 13:03:06 -0600] SF 3487629 430x address mode gets sym= bolic wrong > d42e20d [2012-02-14 11:17:28 -0600] Remove bypassed PCREL relocation gene= ration for source operands > 5e0b242 [2012-02-14 10:52:26 -0600] Confirm that no operands need to be P= CREL adjusted > 3dd285b [2012-02-14 10:51:50 -0600] Expand all reloc selection macros > 75db281 [2012-02-14 08:49:18 -0600] Improve description of relocation for= conditional jumps > 00b8acc [2012-02-14 08:48:19 -0600] Record exemplar instructions for each= pattern > 8c4d424 [2012-02-13 17:33:17 -0600] SF 3487332 gas misassemble symbolic c= onstant > 801c9a3 [2012-02-13 16:33:31 -0600] SF 3487360 gas mis-disassemble symbol= ics > 6245b53 [2012-02-13 14:41:14 -0600] Refactor test for non-PC-relative rel= ocations > 9b86911 [2012-02-13 14:03:53 -0600] Note how to get the opcodes that must= be tested > bb8f6d6 [2012-02-13 13:16:06 -0600] SF 3487361 clra opcode incorrect > 4c24e63 [2012-02-13 13:11:57 -0600] SF 3487364 430x address opcodes ignor= e CG > 423d997 [2012-02-13 11:59:38 -0600] magic number and fix comment > 23b0c4a [2012-02-12 19:31:49 -0600] Reject arithmetic on registers at com= pile time > 2e8cf27 [2012-02-12 18:46:05 -0600] Substitute -1 for constants that are = all ones for the operation width > 4570057 [2012-02-12 18:24:52 -0600] clean up opcode width extraction > 1e31e58 [2012-02-12 17:35:02 -0600] Reorder for clarity > f8d0c92 [2012-02-12 15:40:36 -0600] Avoid premature marking of immediate = operand > 1b239ba [2012-02-12 15:24:43 -0600] Avoid double-converting operand in em= ulated shift operations > 1fe0bda [2012-02-12 13:26:54 -0600] Clean up register recognition and oth= er processing > f6975b1 [2012-02-12 11:56:13 -0600] documentation cleanup > 88e0d46 [2012-02-12 10:58:20 -0600] clean up immediate operand validation > 333db05 [2012-02-12 10:15:20 -0600] clean up local variables in srcoperand > 7ee8609 [2012-02-12 10:02:45 -0600] Clean up dstoperand conversion > 3f486c5 [2012-02-12 09:36:31 -0600] cleanup: constants, remove gratuitous= declaration > d43d131 [2012-02-10 15:17:39 -0600] Replace check_reg with extract_regno > 8251e36 [2012-02-10 14:43:41 -0600] Eliminate magic number where OP_EXP w= as intended > 5c2acd6 [2012-02-10 14:39:35 -0600] Clean up .rpt pseudo-op > 8f31c95 [2012-02-10 13:33:25 -0600] Style cleanup: eliminate C++-style co= mments > 5d7e371 [2012-02-10 12:59:46 -0600] Style cleanup > 2aa2306 [2012-02-10 12:30:04 -0600] Correct #lo/#hi processing to retain = recognition of -1 constant > 764f227 [2012-02-10 11:16:34 -0600] Run everything through GNU indent for= style cleanup > b11e197 [2012-02-10 11:10:10 -0600] Eliminate mask constants in favor of = macros > acd1aef [2012-02-10 10:29:54 -0600] more removal of magic numbers > 7382915 [2012-02-10 09:49:28 -0600] Remove disabled code to display inter= rupt vectors > 1459fea [2012-02-10 09:25:49 -0600] SF 3486454 .rpt disassembles incorrec= tly > c6b03ca [2012-02-10 09:18:35 -0600] SF 3486453 rrux not supported > 82ee322 [2012-02-09 23:20:23 -0600] SF 3486451 430x 20-bit immediates mis= translated > f6013a3 [2012-02-09 23:02:44 -0600] eliminate magic register numbers > 7de23a2 [2012-02-09 22:47:55 -0600] gas: eliminate magic numbers in immed= iate range checks > d01e7e7 [2012-02-09 22:39:19 -0600] convert src/dst operand extractors to= bfd_boolean functions > 97bf578 [2012-02-09 18:54:45 -0600] Remove relaxation and polymorph suppo= rt for MSP430 > 4f26e0d [2012-02-09 11:34:56 -0600] tc-msp430.h: cleanup > a4629d3 [2012-02-09 12:08:52 -0600] Add relevant errata provided by TI > 2c98b77 [2012-01-25 13:38:19 -0600] Update DEV-PHASE for release > f1bde45 [2012-01-19 18:28:35 -0600] Correct version infrastructure to als= o modify release version string > 1285522 [2012-01-11 12:00:05 -0600] SF 3472485 need visible version info = in tool output > 3e579b5 [2011-08-30 09:37:12 -0500] SF 3400750 infomemnobits missing > 4dbee68 [2011-08-23 18:33:24 -0500] SF 3383736 separate info sections > df11b38 [2011-08-03 04:15:21 -0500] Make relocation section definitions c= onsistent with elf.sc > c1e9b02 [2011-08-03 04:10:55 -0500] Clean up data sections > 860d0d0 [2011-08-02 10:06:59 -0500] SF 3143071 error in addend of relocat= ion entry in output > f8871b7 [2011-08-02 16:59:15 -0500] SF 3384754 relocatable links discard = CRT section information > df2ed93 [2011-08-02 16:34:31 -0500] SF 3384766 string constants misplaced= in text section > d139f8a [2011-07-27 11:06:56 -0500] SF 3379341: non-empty ARCH environmen= t variable results unusable ld > dea9a0d [2011-02-10 23:44:12 +0000] Revert 2010-11-02 H.J. Lu. > d67e991 [2011-06-12 11:09:24 -0500] SF 3315471 remove _init_section__ fun= ction > 674669c [2011-05-07 11:43:29 -0500] SF 3293911 gas 2.21 segfault when bui= lding gcc 4.4.5 > 04e54de [2011-04-21 10:02:40 -0500] Avoid complaints in relocatable links > 3d4651b [2011-04-18 16:42:26 -0500] SF 3289064 uniarch binutils missing f= ar section support > 61941d8 [2011-04-13 19:06:23 -0500] SF 3286248 broken #hlo calculation fo= r small constants > 4ecb659 [2011-04-10 21:39:34 -0500] SF 3237855: clean up -mmcu documentat= ion > 492b386 [2011-04-02 09:11:34 -0500] SF 3266079: binutils link does not pr= eserve cpu architecture > 0cf6f04 [2011-04-02 09:09:52 -0500] Clone genelf.em prior to msp430-speci= fic mods > 88c78f9 [2011-03-22 09:55:52 -0500] Store architecture, not CPU, in elf f= lags field > 8b0914d [2011-03-14 12:55:23 -0500] Clean up section management. > 0967a41 [2011-03-12 11:19:17 -0600] SF 3207853: bad constant extraction o= n 64-bit systems > e76d094 [2011-03-12 09:55:14 -0600] SF 3207853: validate llo/lhi/hlo/hhi > bd6984f [2011-03-12 09:28:50 -0600] Update to match current output (white= space variations only) > 4f48d67 [2011-03-02 18:24:57 -0600] SF 3197755: long long type not working > 9ee0da1 [2011-02-20 14:44:58 -0600] Eliminate warning that breaks gcc tes= t infrastructure > 68710d7 [2011-02-10 17:01:58 -0600] SF 3177314: undefined reference with = too many template parameters > 3c372b3 [2011-02-07 10:49:43 -0600] Parse cpu/mpy directives in assembly = code > dbbc6f6 [2011-02-07 09:06:23 -0600] Regenerate > 5877af8 [2011-02-07 09:03:21 -0600] Remove hard-coded MCU-specific inform= ation from msp430 port. > 5083be6 [2011-02-05 21:37:53 -0600] Correct vector start for ISA_24 chips > 1ce656f [2011-02-05 13:56:25 -0600] Regenerate > f07e5a2 [2011-02-05 13:56:08 -0600] Add MCUs supported by msp430all.sh > f4dc7c0 [2011-02-05 13:31:09 -0600] Regenerate > 5dfc571 [2011-02-05 13:29:08 -0600] Update to match MCUs in msp430all.sh > bea8d7b [2011-01-26 11:53:58 -0600] SF 3154622: Correct support for MSP43= 0F2132 > 4674f3a [2011-01-26 11:12:49 -0600] SF 3146404: Support for msp430f550x c= hips > c8aacc6 [2011-01-21 16:01:15 +0200] Add support for msp430f471x3 > e845ac1 [2010-11-14 10:07:12 -0600] SF 3109143: Support value-line MSP430= G22x1 devices > 3909fd6 [2010-11-06 14:31:43 -0500] SF 3096352: Illegal disassembly instr= uction (addx.a R14,R15) > e291e09 [2010-08-29 13:11:44 -0500] SF 3055519: add support for 55xx chips > a0f3a60 [2010-05-27 12:22:04 -0500] Replace undefined cc430x5123 with mis= sing cc430x5133 > aeec5cc [2010-05-27 11:32:07 -0500] Fix info/bsl locations on newer chips > 70aa46c [2011-01-02 10:53:49 -0600] Apply binutils-2.20.patch from revisi= on aac9a66b of mspgcc4 repository. > > diff --git binutils-2.21.1a.orig/bfd/Makefile.am binutils-2.21.1a/bfd/Mak= efile.am > index 39c5295..22741b8 100644 > --- binutils-2.21.1a.orig/bfd/Makefile.am > +++ binutils-2.21.1a/bfd/Makefile.am > @@ -953,10 +953,13 @@ bfdver.h: $(srcdir)/version.h $(srcdir)/Makefile.in > bfd_soversion=3D"$(VERSION)" ;\ > bfd_version_package=3D"\"$(PKGVERSION)\"" ;\ > report_bugs_to=3D"\"$(REPORT_BUGS_TO)\"" ;\ > + bfd_mspgcc_version=3D`sed -n -e 's/.*MSPGCC_VERSION //p' < $(srcdir)/ve= rsion.h` ;\ > if test "x$(RELEASE)" =3D x ; then \ > bfd_version_date=3D`sed -n -e 's/.*DATE //p' < $(srcdir)/version.h` ;\ > - bfd_version_string=3D"\"$(VERSION).$${bfd_version_date}\"" ;\ > + bfd_version_string=3D"\"$(VERSION).$${bfd_version_date} (mspgcc $${bf= d_mspgcc_version})\"" ;\ > bfd_soversion=3D"$(VERSION).$${bfd_version_date}" ;\ > + else\ > + bfd_version_string=3D"\"$(VERSION) (mspgcc $${bfd_mspgcc_version})\""= ;\ > fi ;\ > sed -e "s,@bfd_version@,$$bfd_version," \ > -e "s,@bfd_version_string@,$$bfd_version_string," \ > diff --git binutils-2.21.1a.orig/bfd/Makefile.in binutils-2.21.1a/bfd/Mak= efile.in > index 8ebfcb7..6c730c2 100644 > --- binutils-2.21.1a.orig/bfd/Makefile.in > +++ binutils-2.21.1a/bfd/Makefile.in > @@ -1985,10 +1985,13 @@ bfdver.h: $(srcdir)/version.h $(srcdir)/Makefile.= in > bfd_soversion=3D"$(VERSION)" ;\ > bfd_version_package=3D"\"$(PKGVERSION)\"" ;\ > report_bugs_to=3D"\"$(REPORT_BUGS_TO)\"" ;\ > + bfd_mspgcc_version=3D`sed -n -e 's/.*MSPGCC_VERSION //p' < $(srcdir)/ve= rsion.h` ;\ > if test "x$(RELEASE)" =3D x ; then \ > bfd_version_date=3D`sed -n -e 's/.*DATE //p' < $(srcdir)/version.h` ;\ > - bfd_version_string=3D"\"$(VERSION).$${bfd_version_date}\"" ;\ > + bfd_version_string=3D"\"$(VERSION).$${bfd_version_date} (mspgcc $${bf= d_mspgcc_version})\"" ;\ > bfd_soversion=3D"$(VERSION).$${bfd_version_date}" ;\ > + else\ > + bfd_version_string=3D"\"$(VERSION) (mspgcc $${bfd_mspgcc_version})\""= ;\ > fi ;\ > sed -e "s,@bfd_version@,$$bfd_version," \ > -e "s,@bfd_version_string@,$$bfd_version_string," \ > diff --git binutils-2.21.1a.orig/bfd/archures.c binutils-2.21.1a/bfd/arch= ures.c > index 1867154..9ad71ab 100644 > --- binutils-2.21.1a.orig/bfd/archures.c > +++ binutils-2.21.1a/bfd/archures.c > @@ -398,21 +398,8 @@ DESCRIPTION > . bfd_arch_xstormy16, > .#define bfd_mach_xstormy16 1 > . bfd_arch_msp430, {* Texas Instruments MSP430 architecture. *} > -.#define bfd_mach_msp11 11 > -.#define bfd_mach_msp110 110 > -.#define bfd_mach_msp12 12 > -.#define bfd_mach_msp13 13 > -.#define bfd_mach_msp14 14 > -.#define bfd_mach_msp15 15 > -.#define bfd_mach_msp16 16 > -.#define bfd_mach_msp21 21 > -.#define bfd_mach_msp31 31 > -.#define bfd_mach_msp32 32 > -.#define bfd_mach_msp33 33 > -.#define bfd_mach_msp41 41 > -.#define bfd_mach_msp42 42 > -.#define bfd_mach_msp43 43 > -.#define bfd_mach_msp44 44 > +.#define bfd_mach_msp430 430 > +.#define bfd_mach_msp430x 431 > . bfd_arch_xc16x, {* Infineon's XC16X Series. *} > .#define bfd_mach_xc16x 1 > .#define bfd_mach_xc16xl 2 > diff --git binutils-2.21.1a.orig/bfd/bfd-in2.h binutils-2.21.1a/bfd/bfd-i= n2.h > index 59b1b8f..3ddb9ff 100644 > --- binutils-2.21.1a.orig/bfd/bfd-in2.h > +++ binutils-2.21.1a/bfd/bfd-in2.h > @@ -2085,21 +2085,8 @@ enum bfd_architecture > bfd_arch_xstormy16, > #define bfd_mach_xstormy16 1 > bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ > -#define bfd_mach_msp11 11 > -#define bfd_mach_msp110 110 > -#define bfd_mach_msp12 12 > -#define bfd_mach_msp13 13 > -#define bfd_mach_msp14 14 > -#define bfd_mach_msp15 15 > -#define bfd_mach_msp16 16 > -#define bfd_mach_msp21 21 > -#define bfd_mach_msp31 31 > -#define bfd_mach_msp32 32 > -#define bfd_mach_msp33 33 > -#define bfd_mach_msp41 41 > -#define bfd_mach_msp42 42 > -#define bfd_mach_msp43 43 > -#define bfd_mach_msp44 44 > +#define bfd_mach_msp430 430 > +#define bfd_mach_msp430x 431 > bfd_arch_xc16x, /* Infineon's XC16X Series. */ > #define bfd_mach_xc16x 1 > #define bfd_mach_xc16xl 2 > @@ -4561,6 +4548,26 @@ This is the 5 bits of a value. */ > BFD_RELOC_MSP430_16_BYTE, > BFD_RELOC_MSP430_2X_PCREL, > BFD_RELOC_MSP430_RL_PCREL, > + BFD_RELOC_MSP430X_SRC_BYTE, > + BFD_RELOC_MSP430X_SRC, > + BFD_RELOC_MSP430X_DST_BYTE, > + BFD_RELOC_MSP430X_DST, > + BFD_RELOC_MSP430X_DST_2ND_BYTE, > + BFD_RELOC_MSP430X_DST_2ND, > + BFD_RELOC_MSP430X_PCREL_SRC_BYTE, > + BFD_RELOC_MSP430X_PCREL_SRC, > + BFD_RELOC_MSP430X_PCREL_DST_BYTE, > + BFD_RELOC_MSP430X_PCREL_DST, > + BFD_RELOC_MSP430X_PCREL_DST_2ND, > + BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE, > + BFD_RELOC_MSP430X_S_BYTE, > + BFD_RELOC_MSP430X_S, > + BFD_RELOC_MSP430X_D_BYTE, > + BFD_RELOC_MSP430X_D, > + BFD_RELOC_MSP430X_PCREL_D, > + BFD_RELOC_MSP430X_INDXD, > + BFD_RELOC_MSP430X_PCREL_INDXD, > + BFD_RELOC_MSP430_10, >=20=20 > /* IQ2000 Relocations. */ > BFD_RELOC_IQ2000_OFFSET_16, > diff --git binutils-2.21.1a.orig/bfd/cpu-msp430.c binutils-2.21.1a/bfd/cp= u-msp430.c > index 63c301a..0dac061 100644 > --- binutils-2.21.1a.orig/bfd/cpu-msp430.c > +++ binutils-2.21.1a/bfd/cpu-msp430.c > @@ -23,86 +23,13 @@ > #include "bfd.h" > #include "libbfd.h" >=20=20 > -static const bfd_arch_info_type *compatible > - PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *)); > - > -#define N(addr_bits, machine, print, default, next) \ > -{ \ > - 16, /* 16 bits in a word. */ \ > - addr_bits, /* Bits in an address. */ \ > - 8, /* 8 bits in a byte. */ \ > - bfd_arch_msp430, \ > - machine, /* Machine number. */ \ > - "msp430", /* Architecture name. */ \ > - print, /* Printable name. */ \ > - 1, /* Section align power. */ \ > - default, /* The default machine. */ \ > - compatible, \ > - bfd_default_scan, \ > - next \ > -} > - > -static const bfd_arch_info_type arch_info_struct[] =3D > -{ > - /* msp430x11x. */ > - N (16, bfd_mach_msp11, "msp:11", FALSE, & arch_info_struct[1]), > - > - /* msp430x11x1. */ > - N (16, bfd_mach_msp110, "msp:110", FALSE, & arch_info_struct[2]), > - > - /* msp430x12x. */ > - N (16, bfd_mach_msp12, "msp:12", FALSE, & arch_info_struct[3]), > - > - /* msp430x13x. */ > - N (16, bfd_mach_msp13, "msp:13", FALSE, & arch_info_struct[4]), > - > - /* msp430x14x. */ > - N (16, bfd_mach_msp14, "msp:14", FALSE, & arch_info_struct[5]), > - > - /* msp430x15x. */ > - N (16, bfd_mach_msp15, "msp:15", FALSE, & arch_info_struct[6]), > -=20=20 > - /* msp430x16x. */ > - N (16, bfd_mach_msp16, "msp:16", FALSE, & arch_info_struct[7]), > - > - /* msp430x21x. */ > - N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[8]), > - > - /* msp430x31x. */ > - N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[9]),=20 > - > - /* msp430x32x. */ > - N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[10]),=20 > - > - /* msp430x33x. */ > - N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[11]), > -=20=20 > - /* msp430x41x. */ > - N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[12]), > - > - /* msp430x42x. */ > - N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[13]), > - > - /* msp430x43x. */ > - N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[14]), > - > - /* msp430x44x. */ > - N (16, bfd_mach_msp43, "msp:44", FALSE, NULL) > -}; > - > -const bfd_arch_info_type bfd_msp430_arch =3D > - N (16, bfd_mach_msp14, "msp:14", TRUE, & arch_info_struct[0]); > - > /* This routine is provided two arch_infos and works out which MSP > machine which would be compatible with both and returns a pointer > - to its info structure. */ > - > + to its info structure. */ > static const bfd_arch_info_type * > -compatible (a,b) > - const bfd_arch_info_type * a; > - const bfd_arch_info_type * b; > +compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b) > { > - /* If a & b are for different architectures we can do nothing. */ > + /* If a & b are for different architectures we can do nothing */ > if (a->arch !=3D b->arch) > return NULL; >=20=20 > @@ -111,3 +38,35 @@ compatible (a,b) >=20=20 > return a; > } > + > +/* Architecture for MSP430X and MSP430XV2 */ > +static const bfd_arch_info_type bfd_msp430x_arch =3D { > + 16, /* 16 bits in a word */ > + 20, /* 20 bits in an address */ > + 8, /* 8 bits in a byte */ > + bfd_arch_msp430, > + bfd_mach_msp430x, /* Machine number */ > + "msp430", /* Architecture name. */ > + "msp430:430X", /* Printable name */ > + 1, /* Section align power */ > + FALSE, /* The default machine */ > + compatible, > + bfd_default_scan, > + 0 > +}; > + > +/* Architecture for MSP430 */ > +const bfd_arch_info_type bfd_msp430_arch =3D { > + 16, /* 16 bits in a word */ > + 16, /* 16 bits in an address */ > + 8, /* 8 bits in a byte */ > + bfd_arch_msp430, > + bfd_mach_msp430, /* Machine number */ > + "msp430", /* Architecture name */ > + "msp430:430", /* Printable name */ > + 1, /* Section align power */ > + TRUE, /* The default machine */ > + compatible, > + bfd_default_scan, > + &bfd_msp430x_arch > +}; > diff --git binutils-2.21.1a.orig/bfd/elf32-msp430.c binutils-2.21.1a/bfd/= elf32-msp430.c > index 9a5fb2a..7c5a720 100644 > --- binutils-2.21.1a.orig/bfd/elf32-msp430.c > +++ binutils-2.21.1a/bfd/elf32-msp430.c > @@ -1,5 +1,5 @@ > /* MSP430-specific support for 32-bit ELF > - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010 > + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2012 > Free Software Foundation, Inc. > Contributed by Dmitry Diky >=20=20 > @@ -26,19 +26,41 @@ > #include "libbfd.h" > #include "elf-bfd.h" > #include "elf/msp430.h" > +#include >=20=20 > /* Use RELA instead of REL. */ > #undef USE_REL >=20=20 > -static reloc_howto_type elf_msp430_howto_table[] =3D > -{ > +#define MSP430_MASK_10(_x) ((_x) & 0x000003FF) > +#define MSP430_MASK_16(_x) ((_x) & 0x0000FFFF) > +#define MSP430_MASK_20(_x) ((_x) & 0x000FFFFF) > + > +/* Test that the value is representable in 16 bits, either signed or > + * unsigned */ > +#define MSP430_16_IN_RANGE(_v) ((_v) >=3D -((bfd_signed_vma)1 << 15) && = (_v) < ((bfd_signed_vma)1 << 16)) > + > +/* Test that the value is representable in 15 bits, signed only */ > +#define MSP430_S16_IN_RANGE(_v) ((_v) >=3D -((bfd_signed_vma)1 << 15) &&= (_v) < ((bfd_signed_vma)1 << 15)) > + > +/* Test that the value is representable in 20 bits, either signed or > + * unsigned */ > +#define MSP430_20_IN_RANGE(_v) ((_v) >=3D -((bfd_signed_vma)1 << 19) && = (_v) < ((bfd_signed_vma)1 << 20)) > + > +/* Test that the value is representable in 10 bits, signed only */ > +#define MSP430_S10_IN_RANGE(_v) ((_v) >=3D -((bfd_signed_vma)1 << 9) && = (_v) < ((bfd_signed_vma)1 << 9)) > + > +/* Test whether the value is odd */ > +#define MSP430_ODD(_v) ((_v) & 1) > + > +static reloc_howto_type elf_msp430_howto_table[] =3D { > + /* BFD_RELOC_NONE */ > HOWTO (R_MSP430_NONE, /* type */ > 0, /* rightshift */ > 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 32, /* bitsize */ > FALSE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_bitfield,/* complain_on_overflow */ > + complain_overflow_bitfield, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > "R_MSP430_NONE", /* name */ > FALSE, /* partial_inplace */ > @@ -46,13 +68,15 @@ static reloc_howto_type elf_msp430_howto_table[] =3D > 0, /* dst_mask */ > FALSE), /* pcrel_offset */ >=20=20 > + /* BFD_RELOC_32: Not used by msp430 back end, but invoked perhaps to > + * write elf header fields. */ > HOWTO (R_MSP430_32, /* type */ > 0, /* rightshift */ > 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 32, /* bitsize */ > FALSE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_bitfield,/* complain_on_overflow */ > + complain_overflow_bitfield, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > "R_MSP430_32", /* name */ > FALSE, /* partial_inplace */ > @@ -60,29 +84,33 @@ static reloc_howto_type elf_msp430_howto_table[] =3D > 0xffffffff, /* dst_mask */ > FALSE), /* pcrel_offset */ >=20=20 > - /* A 13 bit PC relative relocation. */ > + /* BFD_RELOC_MSP430_10_PCREL: Same as BFD_RELOC_MSP430_10, but the > + * offset of the storage location is subtracted prior to > + * non-relocatable storage. */ > HOWTO (R_MSP430_10_PCREL, /* type */ > 1, /* rightshift */ > 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 10, /* bitsize */ > TRUE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_bitfield,/* complain_on_overflow */ > + complain_overflow_bitfield, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > - "R_MSP430_13_PCREL", /* name */ > + "R_MSP430_10_PCREL", /* name */ > FALSE, /* partial_inplace */ > - 0xfff, /* src_mask */ > - 0xfff, /* dst_mask */ > + 0x3ff, /* src_mask */ > + 0x3ff, /* dst_mask */ > TRUE), /* pcrel_offset */ >=20=20 > - /* A 16 bit absolute relocation. */ > + /* BFD_RELOC_MSP430_16: Same as BFD_RELOC_MSP430_16_BYTE, but > + * enforces aligned access by rejecting final values that are not > + * even. */ > HOWTO (R_MSP430_16, /* type */ > 0, /* rightshift */ > 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 16, /* bitsize */ > FALSE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_dont,/* complain_on_overflow */ > + complain_overflow_dont, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > "R_MSP430_16", /* name */ > FALSE, /* partial_inplace */ > @@ -90,14 +118,16 @@ static reloc_howto_type elf_msp430_howto_table[] =3D > 0xffff, /* dst_mask */ > FALSE), /* pcrel_offset */ >=20=20 > - /* A 16 bit absolute relocation for command address. */ > + /* BFD_RELOC_MSP430_16_PCREL: Same as BFD_RELOC_MSP430_16, but the > + * offset of the storage location is subtracted prior to > + * non-relocatable storage. */ > HOWTO (R_MSP430_16_PCREL, /* type */ > 1, /* rightshift */ > 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 16, /* bitsize */ > TRUE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_dont,/* complain_on_overflow */ > + complain_overflow_dont, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > "R_MSP430_16_PCREL", /* name */ > FALSE, /* partial_inplace */ > @@ -105,14 +135,16 @@ static reloc_howto_type elf_msp430_howto_table[] =3D > 0xffff, /* dst_mask */ > TRUE), /* pcrel_offset */ >=20=20 > - /* A 16 bit absolute relocation, byte operations. */ > + /* BFD_RELOC_MSP430_16_BYTE: A 16-bit value representing an > + * immediate or offset, generally stored in a instruction word after > + * an opcode. */ > HOWTO (R_MSP430_16_BYTE, /* type */ > 0, /* rightshift */ > 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 16, /* bitsize */ > FALSE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_dont,/* complain_on_overflow */ > + complain_overflow_dont, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > "R_MSP430_16_BYTE", /* name */ > FALSE, /* partial_inplace */ > @@ -120,29 +152,31 @@ static reloc_howto_type elf_msp430_howto_table[] =3D > 0xffff, /* dst_mask */ > FALSE), /* pcrel_offset */ >=20=20 > - /* A 16 bit absolute relocation for command address. */ > - HOWTO (R_MSP430_16_PCREL_BYTE,/* type */ > + /* BFD_RELOC_MSP430_16_PCREL_BYTE: Same as BFD_RELOC_MSP430_16_BYTE, > + * but the offset of the storage location is subtracted prior to > + * non-relocatable storage. */ > + HOWTO (R_MSP430_16_PCREL_BYTE, /* type */ > 1, /* rightshift */ > 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 16, /* bitsize */ > TRUE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_dont,/* complain_on_overflow */ > + complain_overflow_dont, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > - "R_MSP430_16_PCREL_BYTE",/* name */ > + "R_MSP430_16_PCREL_BYTE", /* name */ > FALSE, /* partial_inplace */ > 0xffff, /* src_mask */ > 0xffff, /* dst_mask */ > TRUE), /* pcrel_offset */ >=20=20 > - /* A 13 bit PC relative relocation for complicated polymorphs. */ > + /* OBSOLETE: A 13 bit PC relative relocation for complicated polymorph= s. */ > HOWTO (R_MSP430_2X_PCREL, /* type */ > 1, /* rightshift */ > 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 10, /* bitsize */ > TRUE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_bitfield,/* complain_on_overflow */ > + complain_overflow_bitfield, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > "R_MSP430_2X_PCREL", /* name */ > FALSE, /* partial_inplace */ > @@ -150,20 +184,364 @@ static reloc_howto_type elf_msp430_howto_table[] = =3D > 0xfff, /* dst_mask */ > TRUE), /* pcrel_offset */ >=20=20 > - /* A 16 bit relaxable relocation for command address. */ > + /* OBSOLETE: A 16 bit relaxable relocation for command address. */ > HOWTO (R_MSP430_RL_PCREL, /* type */ > 1, /* rightshift */ > 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > 16, /* bitsize */ > TRUE, /* pc_relative */ > 0, /* bitpos */ > - complain_overflow_dont,/* complain_on_overflow */ > + complain_overflow_dont, /* complain_on_overflow */ > bfd_elf_generic_reloc, /* special_function */ > "R_MSP430_RL_PCREL", /* name */ > FALSE, /* partial_inplace */ > 0, /* src_mask */ > 0xffff, /* dst_mask */ > - TRUE) /* pcrel_offset */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_SRC_BYTE: A 20 bit absolute value: high 4 bits > + * written into bits 10..7 of the extension word, low 16 bits > + * written into the word after the opcode (+4). */ > + HOWTO (R_MSP430X_SRC_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_SRC_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0xfffff, /* src_mask */ > + 0, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_SRC: Same as BFD_RELOC_MSP430X_SRC_BYTE, but > + * enforces aligned access by rejecting final values that are not > + * even. */ > + HOWTO (R_MSP430X_SRC, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_SRC", /* name */ > + FALSE, /* partial_inplace */ > + 0xfffff, /* src_mask */ > + 0, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_DST_BYTE: A 20 bit absolute value: high 4 bits > + * written into bits 3..0 of the extension word, low 16 bits written > + * into the word after the opcode (+4). */ > + HOWTO (R_MSP430X_DST_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_DST_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_DST: Same as BFD_RELOC_MSP430X_DST_BYTE, but > + * enforces aligned access by rejecting final values that are not > + * even. */ > + HOWTO (R_MSP430X_DST, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_DST", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_DST_2ND_BYTE: Same as > + * BFD_RELOC_MSP430X_DST_BYTE, but the low 16 bits written two words > + * after the opcode (+6). */ > + HOWTO (R_MSP430X_DST_2ND_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_DST_2ND_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_DST_2ND: Same as > + * BFD_RELOC_MSP430X_DST_2ND_BYTE, but enforces aligned access by > + * rejecting final values that are not even. */ > + HOWTO (R_MSP430X_DST_2ND, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_DST_2ND", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_SRC_BYTE: Same as > + * BFD_RELOC_MSP430X_SRC_BYTE, but the offset of the storage > + * location is subtracted prior to non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_SRC_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_SRC_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0xfffff, /* src_mask */ > + 0, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_SRC: Same as BFD_RELOC_MSP430X_SRC, but > + * the offset of the storage location is subtracted prior to > + * non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_SRC, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_SRC", /* name */ > + FALSE, /* partial_inplace */ > + 0xfffff, /* src_mask */ > + 0, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_DST_BYTE: Same as > + * BFD_RELOC_MSP430X_DST_BYTE, but the offset of the storage > + * location is subtracted prior to non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_DST_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_DST_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_DST: Same as BFD_RELOC_MSP430X_DST, but > + * the offset of the storage location is subtracted prior to > + * non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_DST, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_DST", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_DST_2ND: Same as > + * BFD_RELOC_MSP430X_DST_2ND, but the offset of the storage location > + * is subtracted prior to non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_DST_2ND, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_DST_2ND", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE: Same as > + * BFD_RELOC_MSP430X_DST_2ND_BYTE, but the offset of the storage > + * location is subtracted prior to non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_DST_2ND_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_DST_2ND_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_S_BYTE: A 20 bit absolute value for address > + * instructions: high 4 bits written into bits 11..8 of the opcode > + * word, low 16 bits written into the word after the opcode > + * (+2). */ > + HOWTO (R_MSP430X_S_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_S_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0xfffff, /* src_mask */ > + 0, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_S: Same as BFD_RELOC_MSP430X_S_BYTE, but > + * enforces aligned access by rejecting final values that are not > + * even. */ > + HOWTO (R_MSP430X_S, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_S", /* name */ > + FALSE, /* partial_inplace */ > + 0xfffff, /* src_mask */ > + 0, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_D_BYTE: A 20 bit absolute value for address > + * instructions: high 4 bits written into bits 3..0 of the opcode > + * word, low 16 bits written into the word after the opcode (+2). */ > + HOWTO (R_MSP430X_D_BYTE, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_D_BYTE", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_D: Same as BFD_RELOC_MSP430X_D_BYTE, but > + * enforces aligned access by rejecting final values that are not > + * even. */ > + HOWTO (R_MSP430X_D, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_D", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_D: Same as BFD_RELOC_MSP430X_D, but the > + * offset of the storage location is subtracted prior to > + * non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_D, /* type */ > + 0, /* rightshift */ > + 2, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 20, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_D", /* name */ > + FALSE, /* partial_inplace */ > + 0, /* src_mask */ > + 0xfffff, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_INDXD: A 16 bit value that will be sign > + * extended and added to a register to produce a 20-bit address for > + * MOVA/CALLA insns: written into the word after the opcode (+2). */ > + HOWTO (R_MSP430X_INDXD, /* type */ > + 0, /* rightshift */ > + 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 16, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_INDXD", /* name */ > + FALSE, /* partial_inplace */ > + 0xffff, /* src_mask */ > + 0xffff, /* dst_mask */ > + FALSE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430X_PCREL_INDXD: Same as BFD_RELOC_MSP430X_INDXD, > + * but the offset of the storage location is subtracted prior to > + * non-relocatable storage. */ > + HOWTO (R_MSP430X_PCREL_INDXD, /* type */ > + 0, /* rightshift */ > + 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 16, /* bitsize */ > + TRUE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430X_PCREL_INDXD", /* name */ > + FALSE, /* partial_inplace */ > + 0xffff, /* src_mask */ > + 0xffff, /* dst_mask */ > + TRUE), /* pcrel_offset */ > + > + /* BFD_RELOC_MSP430_10: A 10-bit value representing a PC-relative > + * offset, used in conditional jump instructions. The relocation > + * value is in bytes, although the representation in the instruction > + * is in words. (NB: The fact-of PC-relative is encoded in the > + * operation: the value itself is not adjusted except to convert > + * from bytes to words.) */ > + HOWTO (R_MSP430_10, /* type */ > + 1, /* rightshift */ > + 1, /* size (0 =3D byte, 1 =3D short, 2 =3D long) */ > + 10, /* bitsize */ > + FALSE, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_bitfield, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_MSP430_10", /* name */ > + FALSE, /* partial_inplace */ > + 0x3ff, /* src_mask */ > + 0x3ff, /* dst_mask */ > + TRUE), /* pcrel_offset */ > }; >=20=20 > /* Map BFD reloc types to MSP430 ELF reloc types. */ > @@ -174,19 +552,42 @@ struct msp430_reloc_map > unsigned int elf_reloc_val; > }; >=20=20 > -static const struct msp430_reloc_map msp430_reloc_map[] =3D > - { > - {BFD_RELOC_NONE, R_MSP430_NONE}, > - {BFD_RELOC_32, R_MSP430_32}, > - {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL}, > - {BFD_RELOC_16, R_MSP430_16_BYTE}, > - {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL}, > - {BFD_RELOC_MSP430_16, R_MSP430_16}, > - {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE}, > - {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE}, > - {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL}, > - {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL} > - }; > +static const struct msp430_reloc_map msp430_reloc_map[] =3D { > + {BFD_RELOC_NONE, R_MSP430_NONE}, > + {BFD_RELOC_32, R_MSP430_32}, > + {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL}, > + {BFD_RELOC_16, R_MSP430_16_BYTE}, > + {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL}, > + {BFD_RELOC_MSP430_16, R_MSP430_16}, > + {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE}, > + {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE}, > + {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL}, > + {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL}, > + > + {BFD_RELOC_MSP430X_SRC_BYTE, R_MSP430X_SRC_BYTE}, > + {BFD_RELOC_MSP430X_SRC, R_MSP430X_SRC}, > + {BFD_RELOC_MSP430X_DST_BYTE, R_MSP430X_DST_BYTE}, > + {BFD_RELOC_MSP430X_DST, R_MSP430X_DST}, > + {BFD_RELOC_MSP430X_DST_2ND_BYTE, R_MSP430X_DST_2ND_BYTE}, > + {BFD_RELOC_MSP430X_DST_2ND, R_MSP430X_DST_2ND}, > + > + {BFD_RELOC_MSP430X_PCREL_SRC_BYTE, R_MSP430X_PCREL_SRC_BYTE}, > + {BFD_RELOC_MSP430X_PCREL_SRC, R_MSP430X_PCREL_SRC}, > + {BFD_RELOC_MSP430X_PCREL_DST_BYTE, R_MSP430X_PCREL_DST_BYTE}, > + {BFD_RELOC_MSP430X_PCREL_DST, R_MSP430X_PCREL_DST}, > + {BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE, R_MSP430X_PCREL_DST_2ND_BYTE}, > + {BFD_RELOC_MSP430X_PCREL_DST_2ND, R_MSP430X_PCREL_DST_2ND}, > + > + {BFD_RELOC_MSP430X_S_BYTE, R_MSP430X_S_BYTE}, > + {BFD_RELOC_MSP430X_S, R_MSP430X_S}, > + {BFD_RELOC_MSP430X_D_BYTE, R_MSP430X_D_BYTE}, > + {BFD_RELOC_MSP430X_D, R_MSP430X_D}, > + {BFD_RELOC_MSP430X_PCREL_D, R_MSP430X_PCREL_D}, > + {BFD_RELOC_MSP430X_INDXD, R_MSP430X_INDXD}, > + {BFD_RELOC_MSP430X_PCREL_INDXD, R_MSP430X_PCREL_INDXD}, > + > + {BFD_RELOC_MSP430_10, R_MSP430_10}, > +}; >=20=20 > static reloc_howto_type * > bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, > @@ -202,15 +603,12 @@ bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBU= TE_UNUSED, > } >=20=20 > static reloc_howto_type * > -bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, > +bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, > const char *r_name) > { > unsigned int i; >=20=20 > - for (i =3D 0; > - i < (sizeof (elf_msp430_howto_table) > - / sizeof (elf_msp430_howto_table[0])); > - i++) > + for (i =3D 0; i < ARRAY_SIZE (elf_msp430_howto_table); i++) > if (elf_msp430_howto_table[i].name !=3D NULL > && strcasecmp (elf_msp430_howto_table[i].name, r_name) =3D=3D 0) > return &elf_msp430_howto_table[i]; > @@ -222,14 +620,19 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUT= E_UNUSED, >=20=20 > static void > msp430_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, > - arelent * cache_ptr, > - Elf_Internal_Rela * dst) > + arelent * cache_ptr, Elf_Internal_Rela * dst) > { > unsigned int r_type; >=20=20 > r_type =3D ELF32_R_TYPE (dst->r_info); > BFD_ASSERT (r_type < (unsigned int) R_MSP430_max); > cache_ptr->howto =3D &elf_msp430_howto_table[r_type]; > + if (r_type !=3D cache_ptr->howto->type) > + { > + fprintf (stderr, "r_type %u !=3D %u =3D %s\n", r_type, > + cache_ptr->howto->type, cache_ptr->howto->name); > + abort (); > + } > } >=20=20 > /* Look through the relocs for a section during the first phase. > @@ -237,7 +640,7 @@ msp430_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSE= D, > virtual table relocs for gc. */ >=20=20 > static bfd_boolean > -elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info * info, > +elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info *info, > asection * sec, const Elf_Internal_Rela * relocs) > { > Elf_Internal_Shdr *symtab_hdr; > @@ -282,107 +685,171 @@ msp430_final_link_relocate (reloc_howto_type * ho= wto, bfd * input_bfd, > { > bfd_reloc_status_type r =3D bfd_reloc_ok; > bfd_vma x; > - bfd_signed_vma srel; > + bfd_signed_vma srel =3D 0; >=20=20 > - switch (howto->type) > + if (howto->type > R_MSP430_32 && howto->type < R_MSP430_max) > { > - case R_MSP430_10_PCREL: > contents +=3D rel->r_offset; > srel =3D (bfd_signed_vma) relocation; > srel +=3D rel->r_addend; > - srel -=3D rel->r_offset; > - srel -=3D 2; /* Branch instructions add 2 to the PC... */ > - srel -=3D (input_section->output_section->vma + > - input_section->output_offset); >=20=20 > - if (srel & 1) > - return bfd_reloc_outofrange; > + if (howto->pc_relative) > + { > + srel -=3D rel->r_offset; > + srel -=3D (input_section->output_section->vma + > + input_section->output_offset); > + } > + > + switch (howto->type) > + { > + case R_MSP430_10_PCREL: > + /* Account for r0 already being incremented by the time the > + * value is applied. */ > + srel -=3D 2; > + break; > + case R_MSP430X_PCREL_D: /* PC relative dst operand of calla */ > + case R_MSP430X_PCREL_INDXD: /* 16-bit idx in mova/bra instruction PC re= lative (symbolic) mode operand */ > + srel -=3D 2; /* operand located 2 bytes after opcode */ > + break; > + case R_MSP430X_PCREL_SRC: /* PC-relative 20-bit address operand */ > + case R_MSP430X_PCREL_SRC_BYTE: > + case R_MSP430X_PCREL_DST: > + case R_MSP430X_PCREL_DST_BYTE: > + srel -=3D 4; /* operand located 4 bytes after opcode */ > + break; > + case R_MSP430X_PCREL_DST_2ND: > + case R_MSP430X_PCREL_DST_2ND_BYTE: > + srel -=3D 6; /* operand located 6 bytes after opcode */ > + break; > + } > + } > + > + switch (howto->type) > + { > + case R_MSP430_10: > + case R_MSP430_10_PCREL: > + if (MSP430_ODD (srel)) > + r =3D bfd_reloc_dangerous; >=20=20 > /* MSP430 addresses commands as words. */ > srel >>=3D 1; >=20=20 > - /* Check for an overflow. */ > - if (srel < -512 || srel > 511) > - return bfd_reloc_overflow; > - > x =3D bfd_get_16 (input_bfd, contents); > - x =3D (x & 0xfc00) | (srel & 0x3ff); > + x =3D (x & 0xfc00) | MSP430_MASK_10 (srel); > bfd_put_16 (input_bfd, x, contents); > + if (r =3D=3D bfd_reloc_ok && !MSP430_S10_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > break; >=20=20 > case R_MSP430_2X_PCREL: > - contents +=3D rel->r_offset; > - srel =3D (bfd_signed_vma) relocation; > - srel +=3D rel->r_addend; > - srel -=3D rel->r_offset; > - srel -=3D 2; /* Branch instructions add 2 to the PC... */ > - srel -=3D (input_section->output_section->vma + > - input_section->output_offset); > - > - if (srel & 1) > - return bfd_reloc_outofrange; > - > - /* MSP430 addresses commands as words. */ > - srel >>=3D 1; > + case R_MSP430_RL_PCREL: > + r =3D bfd_reloc_notsupported; > + break; >=20=20 > - /* Check for an overflow. */ > - if (srel < -512 || srel > 511) > - return bfd_reloc_overflow; > + case R_MSP430_16: > + case R_MSP430_16_PCREL: > + if (MSP430_ODD (srel)) > + r =3D bfd_reloc_dangerous; > + /*FALLTHRU*/; > + case R_MSP430_16_PCREL_BYTE: > + case R_MSP430_16_BYTE: > + bfd_put_16 (input_bfd, MSP430_MASK_16 (srel), contents); > + if (r =3D=3D bfd_reloc_ok && !MSP430_16_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > + break; >=20=20 > + case R_MSP430X_SRC: > + case R_MSP430X_PCREL_SRC: > + if (MSP430_ODD (srel)) > + r =3D bfd_reloc_dangerous; > + /*FALLTHRU*/; > + case R_MSP430X_SRC_BYTE: > + case R_MSP430X_PCREL_SRC_BYTE: > + /* src(19:16) located at positions 10:7 of extension word */ > + /* src(15:0) located just after opcode */ > x =3D bfd_get_16 (input_bfd, contents); > - x =3D (x & 0xfc00) | (srel & 0x3ff); > + /* 4 most-significant bits */ > + x =3D (x & 0xf87f) | ((srel >> 9) & 0x0780); > bfd_put_16 (input_bfd, x, contents); > - /* Handle second jump instruction. */ > - x =3D bfd_get_16 (input_bfd, contents - 2); > - srel +=3D 1; > - x =3D (x & 0xfc00) | (srel & 0x3ff); > - bfd_put_16 (input_bfd, x, contents - 2); > + /* 16 least-significant bits */ > + bfd_put_16 (input_bfd, MSP430_MASK_16 (srel), contents + 4); > + if (r =3D=3D bfd_reloc_ok && !MSP430_20_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > break; >=20=20 > - case R_MSP430_16_PCREL: > - case R_MSP430_RL_PCREL: > - contents +=3D rel->r_offset; > - srel =3D (bfd_signed_vma) relocation; > - srel +=3D rel->r_addend; > - srel -=3D rel->r_offset; > - /* Only branch instructions add 2 to the PC... */ > - srel -=3D (input_section->output_section->vma + > - input_section->output_offset); > - > - if (srel & 1) > - return bfd_reloc_outofrange; > - > - bfd_put_16 (input_bfd, srel & 0xffff, contents); > + case R_MSP430X_DST: > + case R_MSP430X_PCREL_DST: > + if (MSP430_ODD (srel)) > + r =3D bfd_reloc_dangerous; > + /*FALLTHRU*/; > + case R_MSP430X_DST_BYTE: > + case R_MSP430X_PCREL_DST_BYTE: > + /* dst(19:16) located at positions 3:0 of extension word */ > + /* dst(15:0) located just after opcode */ > + x =3D bfd_get_16 (input_bfd, contents); > + x =3D (x & 0xfff0) | ((srel >> 16) & 0x000f); > + bfd_put_16 (input_bfd, x, contents); > + bfd_put_16 (input_bfd, MSP430_MASK_16 (srel), contents + 4); > + if (r =3D=3D bfd_reloc_ok && !MSP430_20_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > break; >=20=20 > - case R_MSP430_16_PCREL_BYTE: > - contents +=3D rel->r_offset; > - srel =3D (bfd_signed_vma) relocation; > - srel +=3D rel->r_addend; > - srel -=3D rel->r_offset; > - /* Only branch instructions add 2 to the PC... */ > - srel -=3D (input_section->output_section->vma + > - input_section->output_offset); > - > - bfd_put_16 (input_bfd, srel & 0xffff, contents); > + case R_MSP430X_DST_2ND: > + case R_MSP430X_PCREL_DST_2ND: > + if (MSP430_ODD (srel)) > + r =3D bfd_reloc_dangerous; > + /*FALLTHRU*/; > + case R_MSP430X_DST_2ND_BYTE: > + case R_MSP430X_PCREL_DST_2ND_BYTE: > + /* dst(19:16) located at positions 3:0 of extension word */ > + /* dst(15:0) located after src(15:0) */ > + x =3D bfd_get_16 (input_bfd, contents); > + x =3D (x & 0xfff0) | ((srel >> 16) & 0x000f); > + bfd_put_16 (input_bfd, x, contents); > + bfd_put_16 (input_bfd, MSP430_MASK_16 (srel), contents + 6); > + if (r =3D=3D bfd_reloc_ok && !MSP430_20_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > break; >=20=20 > - case R_MSP430_16_BYTE: > - contents +=3D rel->r_offset; > - srel =3D (bfd_signed_vma) relocation; > - srel +=3D rel->r_addend; > - bfd_put_16 (input_bfd, srel & 0xffff, contents); > + case R_MSP430X_S: > + if (MSP430_ODD (srel)) > + r =3D bfd_reloc_dangerous; > + /*FALLTHRU*/; > + case R_MSP430X_S_BYTE: > + x =3D bfd_get_16 (input_bfd, contents); > + x =3D (x & 0xf0ff) | ((srel >> 8) & 0x0f00); > + /* src(19:16) located at positions 11:8 of opcode */ > + /* src(15:0) located just after opcode */ > + bfd_put_16 (input_bfd, x, contents); > + bfd_put_16 (input_bfd, MSP430_MASK_16 (srel), contents + 2); > + if (r =3D=3D bfd_reloc_ok && !MSP430_20_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > break; >=20=20 > - case R_MSP430_16: > - contents +=3D rel->r_offset; > - srel =3D (bfd_signed_vma) relocation; > - srel +=3D rel->r_addend; > - > - if (srel & 1) > - return bfd_reloc_notsupported; > + case R_MSP430X_D: > + case R_MSP430X_PCREL_D: > + if (MSP430_ODD (srel)) > + r =3D bfd_reloc_dangerous; > + /*FALLTHRU*/; > + case R_MSP430X_D_BYTE: > + /* dst(19:16) located at positions 3:0 of opcode */ > + /* dst(15:0) located just after opcode */ > + x =3D bfd_get_16 (input_bfd, contents); > + x =3D (x & 0xfff0) | ((srel >> 16) & 0x000f); > + bfd_put_16 (input_bfd, x, contents); > + bfd_put_16 (input_bfd, MSP430_MASK_16 (srel), contents + 2); > + if (r =3D=3D bfd_reloc_ok && !MSP430_20_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > + break; >=20=20 > - bfd_put_16 (input_bfd, srel & 0xffff, contents); > + case R_MSP430X_PCREL_INDXD: > + if (MSP430_ODD (srel)) /*odd address */ > + r =3D bfd_reloc_dangerous; > + /*FALLTHRU*/; > + case R_MSP430X_INDXD: > + bfd_put_16 (input_bfd, MSP430_MASK_16 (srel), contents + 2); > + if (r =3D=3D bfd_reloc_ok && !MSP430_S16_IN_RANGE (srel)) > + r =3D bfd_reloc_overflow; > break; >=20=20 > default: > @@ -398,7 +865,7 @@ msp430_final_link_relocate (reloc_howto_type * howto,= bfd * input_bfd, >=20=20 > static bfd_boolean > elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, > - struct bfd_link_info * info, > + struct bfd_link_info *info, > bfd * input_bfd, > asection * input_section, > bfd_byte * contents, > @@ -441,7 +908,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRI= BUTE_UNUSED, > relocation =3D _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); >=20=20 > name =3D bfd_elf_string_from_elf_section > - (input_bfd, symtab_hdr->sh_link, sym->st_name); > + (input_bfd, symtab_hdr->sh_link, sym->st_name); > name =3D (name =3D=3D NULL) ? bfd_section_name (input_bfd, sec) : nam= e; > } > else > @@ -459,7 +926,12 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTR= IBUTE_UNUSED, > rel, relend, howto, contents); >=20=20 > if (info->relocatable) > - continue; > + { > + BFD_ASSERT (!howto->partial_inplace); > + if (sym !=3D NULL && ELF_ST_TYPE (sym->st_info) =3D=3D STT_SECTION) > + rel->r_addend +=3D sec->output_offset; > + continue; > + } >=20=20 > r =3D msp430_final_link_relocate (howto, input_bfd, input_section, > contents, rel, relocation); > @@ -472,14 +944,13 @@ elf32_msp430_relocate_section (bfd * output_bfd ATT= RIBUTE_UNUSED, > { > case bfd_reloc_overflow: > r =3D info->callbacks->reloc_overflow > - (info, (h ? &h->root : NULL), name, howto->name, > - (bfd_vma) 0, input_bfd, input_section, > - rel->r_offset); > + (info, (h ? &h->root : NULL), name, howto->name, > + (bfd_vma) 0, input_bfd, input_section, rel->r_offset); > break; >=20=20 > case bfd_reloc_undefined: > r =3D info->callbacks->undefined_symbol > - (info, name, input_bfd, input_section, rel->r_offset, TRUE); > + (info, name, input_bfd, input_section, rel->r_offset, TRUE); > break; >=20=20 > case bfd_reloc_outofrange: > @@ -491,7 +962,8 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRI= BUTE_UNUSED, > break; >=20=20 > case bfd_reloc_dangerous: > - msg =3D _("internal error: dangerous relocation"); > + r =3D info->callbacks->reloc_dangerous > + (info, _("unaligned address"), input_bfd, input_section, rel->r_offset= ); > break; >=20=20 > default: > @@ -501,7 +973,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRI= BUTE_UNUSED, >=20=20 > if (msg) > r =3D info->callbacks->warning > - (info, msg, name, input_bfd, input_section, rel->r_offset); > + (info, msg, name, input_bfd, input_section, rel->r_offset); >=20=20 > if (!r) > return FALSE; > @@ -517,646 +989,60 @@ elf32_msp430_relocate_section (bfd * output_bfd AT= TRIBUTE_UNUSED, > number. */ >=20=20 > static void > -bfd_elf_msp430_final_write_processing (bfd * abfd, > - bfd_boolean linker ATTRIBUTE_UNUSED) > +msp430_elf_backend_final_write_processing (bfd * abfd, > + bfd_boolean linker > + ATTRIBUTE_UNUSED) > { > - unsigned long val; > + Elf_Internal_Ehdr *i_ehdrp; > + unsigned long flags; >=20=20 > + i_ehdrp =3D elf_elfheader (abfd); > + i_ehdrp->e_machine =3D EM_MSP430; > + flags =3D 0; > switch (bfd_get_mach (abfd)) > { > default: > - case bfd_mach_msp110: > - val =3D E_MSP430_MACH_MSP430x11x1; > - break; > - > - case bfd_mach_msp11: > - val =3D E_MSP430_MACH_MSP430x11; > - break; > - > - case bfd_mach_msp12: > - val =3D E_MSP430_MACH_MSP430x12; > - break; > - > - case bfd_mach_msp13: > - val =3D E_MSP430_MACH_MSP430x13; > - break; > - > - case bfd_mach_msp14: > - val =3D E_MSP430_MACH_MSP430x14; > - break; > - > - case bfd_mach_msp15: > - val =3D E_MSP430_MACH_MSP430x15; > - break; > - > - case bfd_mach_msp16: > - val =3D E_MSP430_MACH_MSP430x16; > + case bfd_mach_msp430: > + flags =3D EF_MSP430_ARCH_430; > break; > - > - case bfd_mach_msp31: > - val =3D E_MSP430_MACH_MSP430x31; > - break; > - > - case bfd_mach_msp32: > - val =3D E_MSP430_MACH_MSP430x32; > - break; > - > - case bfd_mach_msp33: > - val =3D E_MSP430_MACH_MSP430x33; > - break; > - > - case bfd_mach_msp41: > - val =3D E_MSP430_MACH_MSP430x41; > - break; > - > - case bfd_mach_msp42: > - val =3D E_MSP430_MACH_MSP430x42; > - break; > - > - case bfd_mach_msp43: > - val =3D E_MSP430_MACH_MSP430x43; > - break; > - > - case bfd_mach_msp44: > - val =3D E_MSP430_MACH_MSP430x44; > + case bfd_mach_msp430x: > + flags =3D EF_MSP430_ARCH_430X; > break; > } > - > - elf_elfheader (abfd)->e_machine =3D EM_MSP430; > - elf_elfheader (abfd)->e_flags &=3D ~EF_MSP430_MACH; > - elf_elfheader (abfd)->e_flags |=3D val; > + i_ehdrp->e_flags =3D EF_MSP430_UNIARCH | flags; > } >=20=20 > /* Set the right machine number. */ >=20=20 > static bfd_boolean > -elf32_msp430_object_p (bfd * abfd) > +msp430_elf_backend_object_p (bfd * abfd ATTRIBUTE_UNUSED) > { > - int e_set =3D bfd_mach_msp14; > + Elf_Internal_Ehdr *i_ehdrp; > + int bfd_mach; >=20=20 > - if (elf_elfheader (abfd)->e_machine =3D=3D EM_MSP430 > - || elf_elfheader (abfd)->e_machine =3D=3D EM_MSP430_OLD) > + i_ehdrp =3D elf_elfheader (abfd); > + if (EM_MSP430 !=3D i_ehdrp->e_machine) > + return FALSE; > + if (EF_MSP430_UNIARCH & i_ehdrp->e_flags) > { > - int e_mach =3D elf_elfheader (abfd)->e_flags & EF_MSP430_MACH; > - > - switch (e_mach) > + switch (i_ehdrp->e_flags & EF_MSP430_ARCH) > { > default: > - case E_MSP430_MACH_MSP430x11: > - e_set =3D bfd_mach_msp11; > - break; > - > - case E_MSP430_MACH_MSP430x11x1: > - e_set =3D bfd_mach_msp110; > + case EF_MSP430_ARCH_430: > + bfd_mach =3D bfd_mach_msp430; > break; > - > - case E_MSP430_MACH_MSP430x12: > - e_set =3D bfd_mach_msp12; > - break; > - > - case E_MSP430_MACH_MSP430x13: > - e_set =3D bfd_mach_msp13; > - break; > - > - case E_MSP430_MACH_MSP430x14: > - e_set =3D bfd_mach_msp14; > - break; > - > - case E_MSP430_MACH_MSP430x15: > - e_set =3D bfd_mach_msp15; > - break; > - > - case E_MSP430_MACH_MSP430x16: > - e_set =3D bfd_mach_msp16; > - break; > - > - case E_MSP430_MACH_MSP430x31: > - e_set =3D bfd_mach_msp31; > - break; > - > - case E_MSP430_MACH_MSP430x32: > - e_set =3D bfd_mach_msp32; > - break; > - > - case E_MSP430_MACH_MSP430x33: > - e_set =3D bfd_mach_msp33; > - break; > - > - case E_MSP430_MACH_MSP430x41: > - e_set =3D bfd_mach_msp41; > - break; > - > - case E_MSP430_MACH_MSP430x42: > - e_set =3D bfd_mach_msp42; > - break; > - > - case E_MSP430_MACH_MSP430x43: > - e_set =3D bfd_mach_msp43; > - break; > - > - case E_MSP430_MACH_MSP430x44: > - e_set =3D bfd_mach_msp44; > + case EF_MSP430_ARCH_430X: > + bfd_mach =3D bfd_mach_msp430x; > break; > } > } > - > - return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set); > -} > - > -/* These functions handle relaxing for the msp430. > - Relaxation required only in two cases: > - - Bad hand coding like jumps from one section to another or > - from file to file. > - - Sibling calls. This will affect onlu 'jump label' polymorph. Witho= ut > - relaxing this enlarges code by 2 bytes. Sibcalls implemented but > - do not work in gcc's port by the reason I do not know. > - Anyway, if a relaxation required, user should pass -relax option to t= he > - linker. > - > - There are quite a few relaxing opportunities available on the msp430: > - > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - > - 1. 3 words -> 1 word > - > - eq =3D=3D jeq label jne +4; br lab > - ne !=3D jne label jeq +4; br lab > - lt < jl label jge +4; br lab > - ltu < jlo label lhs +4; br lab > - ge >=3D jge label jl +4; br lab > - geu >=3D jhs label jlo +4; br lab > - > - 2. 4 words -> 1 word > - > - ltn < jn jn +2; jmp +4; br lab > - > - 3. 4 words -> 2 words > - > - gt > jeq +2; jge label jeq +6; jl +4; br label > - gtu > jeq +2; jhs label jeq +6; jlo +4; br label > - > - 4. 4 words -> 2 words and 2 labels > - > - leu <=3D jeq label; jlo label jeq +2; jhs +4; br label > - le <=3D jeq label; jl label jeq +2; jge +4; br label > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - > - codemap for first cases is (labels masked ): > - eq: 0x2002,0x4010,0x0000 -> 0x2400 > - ne: 0x2402,0x4010,0x0000 -> 0x2000 > - lt: 0x3402,0x4010,0x0000 -> 0x3800 > - ltu: 0x2c02,0x4010,0x0000 -> 0x2800 > - ge: 0x3802,0x4010,0x0000 -> 0x3400 > - geu: 0x2802,0x4010,0x0000 -> 0x2c00 > - > - second case: > - ltn: 0x3001,0x3c02,0x4010,0x0000 -> 0x3000 > - > - third case: > - gt: 0x2403,0x3802,0x4010,0x0000 -> 0x2401,0x3400 > - gtu: 0x2403,0x2802,0x4010,0x0000 -> 0x2401,0x2c00 > - > - fourth case: > - leu: 0x2401,0x2c02,0x4010,0x0000 -> 0x2400,0x2800 > - le: 0x2401,0x3402,0x4010,0x0000 -> 0x2400,0x3800 > - > - Unspecified case :) > - jump: 0x4010,0x0000 -> 0x3c00. */ > - > -#define NUMB_RELAX_CODES 12 > -static struct rcodes_s > -{ > - int f0, f1; /* From code. */ > - int t0, t1; /* To code. */ > - int labels; /* Position of labels: 1 - one label at first > - word, 2 - one at second word, 3 - two > - labels at both. */ > - int cdx; /* Words to match. */ > - int bs; /* Shrink bytes. */ > - int off; /* Offset from old label for new code. */ > - int ncl; /* New code length. */ > -} rcode[] =3D > -{/* lab,cdx,bs,off,ncl */ > - { 0x0000, 0x0000, 0x3c00, 0x0000, 1, 0, 2, 2, 2}, /* jump */ > - { 0x0000, 0x2002, 0x2400, 0x0000, 1, 1, 4, 4, 2}, /* eq */ > - { 0x0000, 0x2402, 0x2000, 0x0000, 1, 1, 4, 4, 2}, /* ne */ > - { 0x0000, 0x3402, 0x3800, 0x0000, 1, 1, 4, 4, 2}, /* lt */ > - { 0x0000, 0x2c02, 0x2800, 0x0000, 1, 1, 4, 4, 2}, /* ltu */ > - { 0x0000, 0x3802, 0x3400, 0x0000, 1, 1, 4, 4, 2}, /* ge */ > - { 0x0000, 0x2802, 0x2c00, 0x0000, 1, 1, 4, 4, 2}, /* geu */ > - { 0x3001, 0x3c02, 0x3000, 0x0000, 1, 2, 6, 6, 2}, /* ltn */ > - { 0x2403, 0x3802, 0x2401, 0x3400, 2, 2, 4, 6, 4}, /* gt */ > - { 0x2403, 0x2802, 0x2401, 0x2c00, 2, 2, 4, 6, 4}, /* gtu */ > - { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* leu , 2 labels */ > - { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* le , 2 labels */ > - { 0, 0, 0, 0, 0, 0, 0, 0, 0} > -}; > - > -/* Return TRUE if a symbol exists at the given address. */ > - > -static bfd_boolean > -msp430_elf_symbol_address_p (bfd * abfd, > - asection * sec, > - Elf_Internal_Sym * isym, > - bfd_vma addr) > -{ > - Elf_Internal_Shdr *symtab_hdr; > - unsigned int sec_shndx; > - Elf_Internal_Sym *isymend; > - struct elf_link_hash_entry **sym_hashes; > - struct elf_link_hash_entry **end_hashes; > - unsigned int symcount; > - > - sec_shndx =3D _bfd_elf_section_from_bfd_section (abfd, sec); > - > - /* Examine all the local symbols. */ > - symtab_hdr =3D &elf_tdata (abfd)->symtab_hdr; > - for (isymend =3D isym + symtab_hdr->sh_info; isym < isymend; isym++) > - if (isym->st_shndx =3D=3D sec_shndx && isym->st_value =3D=3D addr) > - return TRUE; > - > - symcount =3D (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) > - - symtab_hdr->sh_info); > - sym_hashes =3D elf_sym_hashes (abfd); > - end_hashes =3D sym_hashes + symcount; > - for (; sym_hashes < end_hashes; sym_hashes++) > + else > { > - struct elf_link_hash_entry *sym_hash =3D *sym_hashes; > - > - if ((sym_hash->root.type =3D=3D bfd_link_hash_defined > - || sym_hash->root.type =3D=3D bfd_link_hash_defweak) > - && sym_hash->root.u.def.section =3D=3D sec > - && sym_hash->root.u.def.value =3D=3D addr) > - return TRUE; > + bfd_mach =3D bfd_mach_msp430; > } > - > - return FALSE; > + return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, bfd_mach); > } >=20=20 > -/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has= sec_shndx) > - referenced from current and other sections */ > -static bfd_boolean > -msp430_elf_relax_adjust_locals(bfd * abfd, asection * sec, bfd_vma addr, > - int count, unsigned int sec_shndx, bfd_vma toaddr) > -{ > - Elf_Internal_Shdr *symtab_hdr; > - Elf_Internal_Rela *irel; > - Elf_Internal_Rela *irelend; > - Elf_Internal_Sym *isym; > - > - irel =3D elf_section_data (sec)->relocs; > - irelend =3D irel + sec->reloc_count; > - symtab_hdr =3D & elf_tdata (abfd)->symtab_hdr; > - isym =3D (Elf_Internal_Sym *) symtab_hdr->contents; > -=20=20 > - for (irel =3D elf_section_data (sec)->relocs; irel < irelend; irel++) > - { > - int sidx =3D ELF32_R_SYM(irel->r_info); > - Elf_Internal_Sym *lsym =3D isym + sidx; > -=20=20=20=20=20=20 > - /* Adjust symbols referenced by .sec+0xXX */ > - if (irel->r_addend > addr && irel->r_addend < toaddr=20 > - && lsym->st_shndx =3D=3D sec_shndx) > - irel->r_addend -=3D count; > - } > -=20=20 > - return TRUE; > -} > - > -/* Delete some bytes from a section while relaxing. */ > - > -static bfd_boolean > -msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr, > - int count) > -{ > - Elf_Internal_Shdr *symtab_hdr; > - unsigned int sec_shndx; > - bfd_byte *contents; > - Elf_Internal_Rela *irel; > - Elf_Internal_Rela *irelend; > - bfd_vma toaddr; > - Elf_Internal_Sym *isym; > - Elf_Internal_Sym *isymend; > - struct elf_link_hash_entry **sym_hashes; > - struct elf_link_hash_entry **end_hashes; > - unsigned int symcount; > - asection *p; > - > - sec_shndx =3D _bfd_elf_section_from_bfd_section (abfd, sec); > - > - contents =3D elf_section_data (sec)->this_hdr.contents; > - > - toaddr =3D sec->size; > - > - irel =3D elf_section_data (sec)->relocs; > - irelend =3D irel + sec->reloc_count; > - > - /* Actually delete the bytes. */ > - memmove (contents + addr, contents + addr + count, > - (size_t) (toaddr - addr - count)); > - sec->size -=3D count; > - > - /* Adjust all the relocs. */ > - symtab_hdr =3D & elf_tdata (abfd)->symtab_hdr; > - isym =3D (Elf_Internal_Sym *) symtab_hdr->contents; > - for (irel =3D elf_section_data (sec)->relocs; irel < irelend; irel++) > - { > - /* Get the new reloc address. */ > - if ((irel->r_offset > addr && irel->r_offset < toaddr)) > - irel->r_offset -=3D count; > - } > - > - for (p =3D abfd->sections; p !=3D NULL; p =3D p->next) > - msp430_elf_relax_adjust_locals(abfd,p,addr,count,sec_shndx,toaddr); > -=20=20 > - /* Adjust the local symbols defined in this section. */ > - symtab_hdr =3D & elf_tdata (abfd)->symtab_hdr; > - isym =3D (Elf_Internal_Sym *) symtab_hdr->contents; > - for (isymend =3D isym + symtab_hdr->sh_info; isym < isymend; isym++) > - if (isym->st_shndx =3D=3D sec_shndx > - && isym->st_value > addr && isym->st_value < toaddr) > - isym->st_value -=3D count; > - > - /* Now adjust the global symbols defined in this section. */ > - symcount =3D (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) > - - symtab_hdr->sh_info); > - sym_hashes =3D elf_sym_hashes (abfd); > - end_hashes =3D sym_hashes + symcount; > - for (; sym_hashes < end_hashes; sym_hashes++) > - { > - struct elf_link_hash_entry *sym_hash =3D *sym_hashes; > - > - if ((sym_hash->root.type =3D=3D bfd_link_hash_defined > - || sym_hash->root.type =3D=3D bfd_link_hash_defweak) > - && sym_hash->root.u.def.section =3D=3D sec > - && sym_hash->root.u.def.value > addr > - && sym_hash->root.u.def.value < toaddr) > - sym_hash->root.u.def.value -=3D count; > - } > - > - return TRUE; > -} > - > - > -static bfd_boolean > -msp430_elf_relax_section (bfd * abfd, asection * sec, > - struct bfd_link_info * link_info, > - bfd_boolean * again) > -{ > - Elf_Internal_Shdr * symtab_hdr; > - Elf_Internal_Rela * internal_relocs; > - Elf_Internal_Rela * irel; > - Elf_Internal_Rela * irelend; > - bfd_byte * contents =3D NULL; > - Elf_Internal_Sym * isymbuf =3D NULL; > - > - /* Assume nothing changes. */ > - *again =3D FALSE; > - > - /* We don't have to do anything for a relocatable link, if > - this section does not have relocs, or if this is not a > - code section. */ > - if (link_info->relocatable > - || (sec->flags & SEC_RELOC) =3D=3D 0 > - || sec->reloc_count =3D=3D 0 || (sec->flags & SEC_CODE) =3D=3D 0) > - return TRUE; > - > - symtab_hdr =3D & elf_tdata (abfd)->symtab_hdr; > - > - /* Get a copy of the native relocations. */ > - internal_relocs =3D > - _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_me= mory); > - if (internal_relocs =3D=3D NULL) > - goto error_return; > - > - /* Walk through them looking for relaxing opportunities. */ > - irelend =3D internal_relocs + sec->reloc_count; > - for (irel =3D internal_relocs; irel < irelend; irel++) > - { > - bfd_vma symval; > - > - /* If this isn't something that can be relaxed, then ignore > - this reloc. */ > - if (ELF32_R_TYPE (irel->r_info) !=3D (int) R_MSP430_RL_PCREL) > - continue; > - > - /* Get the section contents if we haven't done so already. */ > - if (contents =3D=3D NULL) > - { > - /* Get cached copy if it exists. */ > - if (elf_section_data (sec)->this_hdr.contents !=3D NULL) > - contents =3D elf_section_data (sec)->this_hdr.contents; > - else if (! bfd_malloc_and_get_section (abfd, sec, &contents)) > - goto error_return; > - } > - > - /* Read this BFD's local symbols if we haven't done so already. */ > - if (isymbuf =3D=3D NULL && symtab_hdr->sh_info !=3D 0) > - { > - isymbuf =3D (Elf_Internal_Sym *) symtab_hdr->contents; > - if (isymbuf =3D=3D NULL) > - isymbuf =3D bfd_elf_get_elf_syms (abfd, symtab_hdr, > - symtab_hdr->sh_info, 0, > - NULL, NULL, NULL); > - if (isymbuf =3D=3D NULL) > - goto error_return; > - } > - > - /* Get the value of the symbol referred to by the reloc. */ > - if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) > - { > - /* A local symbol. */ > - Elf_Internal_Sym *isym; > - asection *sym_sec; > - > - isym =3D isymbuf + ELF32_R_SYM (irel->r_info); > - if (isym->st_shndx =3D=3D SHN_UNDEF) > - sym_sec =3D bfd_und_section_ptr; > - else if (isym->st_shndx =3D=3D SHN_ABS) > - sym_sec =3D bfd_abs_section_ptr; > - else if (isym->st_shndx =3D=3D SHN_COMMON) > - sym_sec =3D bfd_com_section_ptr; > - else > - sym_sec =3D bfd_section_from_elf_index (abfd, isym->st_shndx); > - symval =3D (isym->st_value > - + sym_sec->output_section->vma + sym_sec->output_offset); > - } > - else > - { > - unsigned long indx; > - struct elf_link_hash_entry *h; > - > - /* An external symbol. */ > - indx =3D ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; > - h =3D elf_sym_hashes (abfd)[indx]; > - BFD_ASSERT (h !=3D NULL); > - > - if (h->root.type !=3D bfd_link_hash_defined > - && h->root.type !=3D bfd_link_hash_defweak) > - /* This appears to be a reference to an undefined > - symbol. Just ignore it--it will be caught by the > - regular reloc processing. */ > - continue; > - > - symval =3D (h->root.u.def.value > - + h->root.u.def.section->output_section->vma > - + h->root.u.def.section->output_offset); > - } > - > - /* For simplicity of coding, we are going to modify the section > - contents, the section relocs, and the BFD symbol table. We > - must tell the rest of the code not to free up this > - information. It would be possible to instead create a table > - of changes which have to be made, as is done in coff-mips.c; > - that would be more work, but would require less memory when > - the linker is run. */ > - > - /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative > - branch. */ > - /* Paranoia? paranoia... */=20=20=20=20=20=20 > - if (ELF32_R_TYPE (irel->r_info) =3D=3D (int) R_MSP430_RL_PCREL) > - { > - bfd_vma value =3D symval; > - > - /* Deal with pc-relative gunk. */ > - value -=3D (sec->output_section->vma + sec->output_offset); > - value -=3D irel->r_offset; > - value +=3D irel->r_addend; > - > - /* See if the value will fit in 10 bits, note the high value is > - 1016 as the target will be two bytes closer if we are > - able to relax. */ > - if ((long) value < 1016 && (long) value > -1016) > - { > - int code0 =3D 0, code1 =3D 0, code2 =3D 0; > - int i; > - struct rcodes_s *rx; > - > - /* Get the opcode. */ > - if (irel->r_offset >=3D 6) > - code0 =3D bfd_get_16 (abfd, contents + irel->r_offset - 6); > - > - if (irel->r_offset >=3D 4) > - code1 =3D bfd_get_16 (abfd, contents + irel->r_offset - 4); > - > - code2 =3D bfd_get_16 (abfd, contents + irel->r_offset - 2); > - > - if (code2 !=3D 0x4010) > - continue; > - > - /* Check r4 and r3. */ > - for (i =3D NUMB_RELAX_CODES - 1; i >=3D 0; i--) > - { > - rx =3D &rcode[i]; > - if (rx->cdx =3D=3D 2 && rx->f0 =3D=3D code0 && rx->f1 =3D=3D code1) > - break; > - else if (rx->cdx =3D=3D 1 && rx->f1 =3D=3D code1) > - break; > - else if (rx->cdx =3D=3D 0) /* This is an unconditional jump. */ > - break; > - } > - > - /* Check labels: > - .Label0: ; we do not care about this label > - jeq +6 > - .Label1: ; make sure there is no label here > - jl +4 > - .Label2: ; make sure there is no label here > - br .Label_dst > - > - So, if there is .Label1 or .Label2 we cannot relax this code. > - This actually should not happen, cause for relaxable > - instructions we use RL_PCREL reloc instead of 16_PCREL. > - Will change this in the future. */ > - > - if (rx->cdx > 0 > - && msp430_elf_symbol_address_p (abfd, sec, isymbuf, > - irel->r_offset - 2)) > - continue; > - if (rx->cdx > 1 > - && msp430_elf_symbol_address_p (abfd, sec, isymbuf, > - irel->r_offset - 4)) > - continue; > - > - /* Note that we've changed the relocs, section contents, etc. */ > - elf_section_data (sec)->relocs =3D internal_relocs; > - elf_section_data (sec)->this_hdr.contents =3D contents; > - symtab_hdr->contents =3D (unsigned char *) isymbuf; > - > - /* Fix the relocation's type. */ > - if (rx->labels =3D=3D 3) /* Handle special cases. */ > - irel->r_info =3D ELF32_R_INFO (ELF32_R_SYM (irel->r_info), > - R_MSP430_2X_PCREL); > - else > - irel->r_info =3D ELF32_R_INFO (ELF32_R_SYM (irel->r_info), > - R_MSP430_10_PCREL); > - > - /* Fix the opcode right way. */ > - bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off); > - if (rx->t1) > - bfd_put_16 (abfd, rx->t1, > - contents + irel->r_offset - rx->off + 2); > - > - /* Delete bytes. */ > - if (!msp430_elf_relax_delete_bytes (abfd, sec, > - irel->r_offset - rx->off + > - rx->ncl, rx->bs)) > - goto error_return; > - > - /* Handle unconditional jumps. */ > - if (rx->cdx =3D=3D 0) > - irel->r_offset -=3D 2; > - > - /* That will change things, so, we should relax again. > - Note that this is not required, and it may be slow. */ > - *again =3D TRUE; > - } > - } > - } > - > - if (isymbuf !=3D NULL && symtab_hdr->contents !=3D (unsigned char *) i= symbuf) > - { > - if (!link_info->keep_memory) > - free (isymbuf); > - else > - { > - /* Cache the symbols for elf_link_input_bfd. */ > - symtab_hdr->contents =3D (unsigned char *) isymbuf; > - } > - } > - > - if (contents !=3D NULL > - && elf_section_data (sec)->this_hdr.contents !=3D contents) > - { > - if (!link_info->keep_memory) > - free (contents); > - else > - { > - /* Cache the section contents for elf_link_input_bfd. */ > - elf_section_data (sec)->this_hdr.contents =3D contents; > - } > - } > - > - if (internal_relocs !=3D NULL > - && elf_section_data (sec)->relocs !=3D internal_relocs) > - free (internal_relocs); > - > - return TRUE; > - > -error_return: > - if (isymbuf !=3D NULL && symtab_hdr->contents !=3D (unsigned char *) i= symbuf) > - free (isymbuf); > - if (contents !=3D NULL > - && elf_section_data (sec)->this_hdr.contents !=3D contents) > - free (contents); > - if (internal_relocs !=3D NULL > - && elf_section_data (sec)->relocs !=3D internal_relocs) > - free (internal_relocs); > - > - return FALSE; > -} > - > - > #define ELF_ARCH bfd_arch_msp430 > #define ELF_MACHINE_CODE EM_MSP430 > #define ELF_MACHINE_ALT1 EM_MSP430_OLD > @@ -1167,13 +1053,11 @@ error_return: > #define TARGET_LITTLE_NAME "elf32-msp430" >=20=20 > #define elf_info_to_howto msp430_info_to_howto_rela > -#define elf_info_to_howto_rel NULL > #define elf_backend_relocate_section elf32_msp430_relocate_secti= on > #define elf_backend_check_relocs elf32_msp430_check_relocs > #define elf_backend_can_gc_sections 1 > -#define elf_backend_final_write_processing bfd_elf_msp430_final_write_= processing > -#define elf_backend_object_p elf32_msp430_object_p > #define elf_backend_post_process_headers _bfd_elf_set_osabi > -#define bfd_elf32_bfd_relax_section msp430_elf_relax_section > +#define elf_backend_final_write_processing msp430_elf_backend_final_wr= ite_processing > +#define elf_backend_object_p msp430_elf_backend_object_p >=20=20 > #include "elf32-target.h" > diff --git binutils-2.21.1a.orig/bfd/libbfd.h binutils-2.21.1a/bfd/libbfd= .h > index e706ce4..01900e2 100644 > --- binutils-2.21.1a.orig/bfd/libbfd.h > +++ binutils-2.21.1a/bfd/libbfd.h > @@ -2165,6 +2165,26 @@ static const char *const bfd_reloc_code_real_names= [] =3D { "@@uninitialized@@", > "BFD_RELOC_MSP430_16_BYTE", > "BFD_RELOC_MSP430_2X_PCREL", > "BFD_RELOC_MSP430_RL_PCREL", > + "BFD_RELOC_MSP430X_SRC_BYTE", > + "BFD_RELOC_MSP430X_SRC", > + "BFD_RELOC_MSP430X_DST_BYTE", > + "BFD_RELOC_MSP430X_DST", > + "BFD_RELOC_MSP430X_DST_2ND_BYTE", > + "BFD_RELOC_MSP430X_DST_2ND", > + "BFD_RELOC_MSP430X_PCREL_SRC_BYTE", > + "BFD_RELOC_MSP430X_PCREL_SRC", > + "BFD_RELOC_MSP430X_PCREL_DST_BYTE", > + "BFD_RELOC_MSP430X_PCREL_DST", > + "BFD_RELOC_MSP430X_PCREL_DST_2ND", > + "BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE", > + "BFD_RELOC_MSP430X_S_BYTE", > + "BFD_RELOC_MSP430X_S", > + "BFD_RELOC_MSP430X_D_BYTE", > + "BFD_RELOC_MSP430X_D", > + "BFD_RELOC_MSP430X_PCREL_D", > + "BFD_RELOC_MSP430X_INDXD", > + "BFD_RELOC_MSP430X_PCREL_INDXD", > + "BFD_RELOC_MSP430_10", > "BFD_RELOC_IQ2000_OFFSET_16", > "BFD_RELOC_IQ2000_OFFSET_21", > "BFD_RELOC_IQ2000_UHI16", > diff --git binutils-2.21.1a.orig/bfd/reloc.c binutils-2.21.1a/bfd/reloc.c > index 5a428a2..9bade10 100644 > --- binutils-2.21.1a.orig/bfd/reloc.c > +++ binutils-2.21.1a/bfd/reloc.c > @@ -5216,6 +5216,46 @@ ENUMX > BFD_RELOC_MSP430_2X_PCREL > ENUMX > BFD_RELOC_MSP430_RL_PCREL > +ENUMX > + BFD_RELOC_MSP430X_SRC_BYTE > +ENUMX > + BFD_RELOC_MSP430X_SRC > +ENUMX > + BFD_RELOC_MSP430X_DST_BYTE > +ENUMX > + BFD_RELOC_MSP430X_DST > +ENUMX > + BFD_RELOC_MSP430X_DST_2ND_BYTE > +ENUMX > + BFD_RELOC_MSP430X_DST_2ND > +ENUMX > + BFD_RELOC_MSP430X_PCREL_SRC_BYTE > +ENUMX > + BFD_RELOC_MSP430X_PCREL_SRC > +ENUMX > + BFD_RELOC_MSP430X_PCREL_DST_BYTE > +ENUMX > + BFD_RELOC_MSP430X_PCREL_DST > +ENUMX > + BFD_RELOC_MSP430X_PCREL_DST_2ND > +ENUMX > + BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE > +ENUMX > + BFD_RELOC_MSP430X_S_BYTE > +ENUMX > + BFD_RELOC_MSP430X_S > +ENUMX > + BFD_RELOC_MSP430X_D_BYTE > +ENUMX > + BFD_RELOC_MSP430X_D > +ENUMX > + BFD_RELOC_MSP430X_PCREL_D > +ENUMX > + BFD_RELOC_MSP430X_INDXD > +ENUMX > + BFD_RELOC_MSP430X_PCREL_INDXD > +ENUMX > + BFD_RELOC_MSP430_10 > ENUMDOC > msp430 specific relocation codes >=20=20 > diff --git binutils-2.21.1a.orig/bfd/version.h binutils-2.21.1a/bfd/versi= on.h > index d4b0e51..e821f31 100644 > --- binutils-2.21.1a.orig/bfd/version.h > +++ binutils-2.21.1a/bfd/version.h > @@ -1,4 +1,5 @@ > #define BFD_VERSION_DATE 20110627 > +#define BFD_MSPGCC_VERSION LTS 20120406 unpatched > #define BFD_VERSION @bfd_version@ > #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ > #define REPORT_BUGS_TO @report_bugs_to@ > diff --git binutils-2.21.1a.orig/gas/config/tc-msp430.c binutils-2.21.1a/= gas/config/tc-msp430.c > index 98d90c6..f0241d6 100644 > --- binutils-2.21.1a.orig/gas/config/tc-msp430.c > +++ binutils-2.21.1a/gas/config/tc-msp430.c > @@ -1,6 +1,6 @@ > /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430 >=20=20 > - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 > + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2012 > Free Software Foundation, Inc. > Contributed by Dmitry Diky >=20=20 > @@ -23,143 +23,13 @@ >=20=20 > #include >=20=20 > -#define PUSH_1X_WORKAROUND > #include "as.h" > #include "subsegs.h" > #include "opcode/msp430.h" > #include "safe-ctype.h" > #include "dwarf2dbg.h" >=20=20 > -/* We will disable polymorphs by default because it is dangerous. > - The potential problem here is the following: assume we got the > - following code: > - > - jump .l1 > - nop > - jump subroutine ; external symbol > - .l1: > - nop > - ret > -=20=20=20 > - In case of assembly time relaxation we'll get: > - 0: jmp .l1 <.text +0x08> (reloc deleted) > - 2: nop > - 4: br subroutine > - .l1: > - 8: nop > - 10: ret > - > - If the 'subroutine' is within +-1024 bytes range then linker > - will produce: > - 0: jmp .text +0x08 > - 2: nop > - 4: jmp subroutine > - .l1: > - 6: nop > - 8: ret ; 'jmp .text +0x08' will land here. WRONG!!! > - > - The workaround is the following: > - 1. Declare global var enable_polymorphs which set to 1 via option -mp. > - 2. Declare global var enable_relax which set to 1 via option -mQ. > - > - If polymorphs are enabled, and relax isn't, treat all jumps as long j= umps, > - do not delete any relocs and leave them for linker. > -=20=20=20 > - If relax is enabled, relax at assembly time and kill relocs as necess= ary. */ > - > -int msp430_enable_relax; > -int msp430_enable_polys; > - > -/* GCC uses the some condition codes which we'll > - implement as new polymorph instructions. > -=20=20 > - COND EXPL SHORT JUMP LONG JUMP > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - eq =3D=3D jeq jne +4; br lab > - ne !=3D jne jeq +4; br lab > - > - ltn honours no-overflow flag > - ltn < jn jn +2; jmp +4; br lab > - > - lt < jl jge +4; br lab=20 > - ltu < jlo lhs +4; br lab > - le <=3D see below > - leu <=3D see below > - > - gt > see below > - gtu > see below > - ge >=3D jge jl +4; br lab > - geu >=3D jhs jlo +4; br lab > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - > - Therefore, new opcodes are (BranchEQ -> beq; and so on...) > - beq,bne,blt,bltn,bltu,bge,bgeu > - 'u' means unsigned compares=20 > -=20=20 > - Also, we add 'jump' instruction: > - jump UNCOND -> jmp br lab > - > - They will have fmt =3D=3D 4, and insn_opnumb =3D=3D number of instruc= tion. */ > - > -struct rcodes_s=20 > -{ > - char * name; > - int index; /* Corresponding insn_opnumb. */ > - int sop; /* Opcode if jump length is short. */ > - long lpos; /* Label position. */ > - long lop0; /* Opcode 1 _word_ (16 bits). */ > - long lop1; /* Opcode second word. */ > - long lop2; /* Opcode third word. */ > -}; > - > -#define MSP430_RLC(n,i,sop,o1) \ > - {#n, i, sop, 2, (o1 + 2), 0x4010, 0} > - > -static struct rcodes_s msp430_rcodes[] =3D=20 > -{ > - MSP430_RLC (beq, 0, 0x2400, 0x2000), > - MSP430_RLC (bne, 1, 0x2000, 0x2400), > - MSP430_RLC (blt, 2, 0x3800, 0x3400), > - MSP430_RLC (bltu, 3, 0x2800, 0x2c00), > - MSP430_RLC (bge, 4, 0x3400, 0x3800), > - MSP430_RLC (bgeu, 5, 0x2c00, 0x2800), > - {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010}, > - {"jump", 7, 0x3c00, 1, 0x4010, 0, 0}, > - {0,0,0,0,0,0,0} > -}; > -#undef MSP430_RLC > - > - > -/* More difficult than above and they have format 5. > -=20=20=20 > - COND EXPL SHORT LONG > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - gt > jeq +2; jge label jeq +6; jl +4; br label > - gtu > jeq +2; jhs label jeq +6; jlo +4; br label > - leu <=3D jeq label; jlo label jeq +2; jhs +4; br label > - le <=3D jeq label; jl label jeq +2; jge +4; br label > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ > - > -struct hcodes_s=20 > -{ > - char * name;=09 > - int index; /* Corresponding insn_opnumb. */ > - int tlab; /* Number of labels in short mode. */ > - int op0; /* Opcode for first word of short jump. */ > - int op1; /* Opcode for second word of short jump. */ > - int lop0; /* Opcodes for long jump mode. */ > - int lop1; > - int lop2; > -}; > - > -static struct hcodes_s msp430_hcodes[] =3D=20 > -{ > - {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 }, > - {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 }, > - {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 }, > - {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 }, > - {0,0,0,0,0,0,0,0} > -}; > +static int msp430x_repeats; >=20=20 > const char comment_chars[] =3D ";"; > const char line_comment_chars[] =3D "#"; > @@ -167,177 +37,596 @@ const char line_separator_chars[] =3D "{"; > const char EXP_CHARS[] =3D "eE"; > const char FLT_CHARS[] =3D "dD"; >=20=20 > -/* Handle long expressions. */ > -extern LITTLENUM_TYPE generic_bignum[]; > - > static struct hash_control *msp430_hash; > - > -/* Relaxations. */ > -#define STATE_UNCOND_BRANCH 1 /* jump */ > -#define STATE_NOOV_BRANCH 3 /* bltn */ > -#define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */ > -#define STATE_EMUL_BRANCH 4 > - > -#define CNRL 2 > -#define CUBL 4 > -#define CNOL 8 > -#define CSBL 6 > -#define CEBL 4 > - > -/* Length. */ > -#define STATE_BITS10 1 /* wild guess. short jump */ > -#define STATE_WORD 2 /* 2 bytes pc rel. addr. more */ > -#define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */ > - > -#define ENCODE_RELAX(what,length) (((what) << 2) + (length)) > -#define RELAX_STATE(s) ((s) & 3) > -#define RELAX_LEN(s) ((s) >> 2) > -#define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1) > - > -relax_typeS md_relax_table[] =3D > +static symbolS *msp430_register_table[REGNO_MAX + 1]; > + > +/* TRUE iff the operand includes an offset encoded into or after the > + * instruction (formerly mode=3D=3DOP_EXP). */ > +#define OP_HAS_IMMEDIATE(_op) \ > + (((_op).am =3D=3D AMs_Immediate && (_op).reg =3D=3D REGNO_PC) \ > + ||((_op).am =3D=3D AM_Indexed && (_op).reg !=3D REGNO_CG2)) > + > +/* TRUE iff the operand is an index offset to a register that might > + * have an odd value. This is used in verifying that the actual > + * offset may be even, thus allowing its use for aligned addresses. */ > +#define OP_INDEXED_PERMITS_ODD(_op) \ > + ((_op).am =3D=3D AM_Indexed \ > + && (_op).reg !=3D REGNO_PC \ > + && (_op).reg !=3D REGNO_CG1 \ > + && (_op).reg !=3D REGNO_SP) > + > +/* TRUE iff the operand is an immediate appearing in a destination > + * operand in a context where the value of that immediate is permitted > + * to be odd. This is a legacy check to ensure that offsets added to > + * registers known to be even will produce a word-aligned address > + * (legacy did not check SP, which this does). */ > +#define OP_DST_IMMEDIATE_PERMITS_ODD(_op) \ > + OP_INDEXED_PERMITS_ODD(_op) > + > +/* TRUE iff the operand is an immediate appearing in a source operand > + * in a context where the value of that immediate is permitted to be > + * odd. This is a legacy check to ensure that offsets added to > + * registers known to be even will produce a word-aligned address > + * (legacy did not check SP, which this does). */ > +#define OP_SRC_IMMEDIATE_PERMITS_ODD(_op) \ > + (((_op).am =3D=3D AMs_Immediate && (_op).reg =3D=3D REGNO_PC) \ > + || OP_DST_IMMEDIATE_PERMITS_ODD(_op)) > + > +enum immediate_range_e > { > - /* Unused. */ > - {1, 1, 0, 0}, > - {1, 1, 0, 0}, > - {1, 1, 0, 0}, > - {1, 1, 0, 0}, > - > - /* Unconditional jump. */ > - {1, 1, 8, 5}, > - {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /= * state 10 bits displ */ > - {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state = word */ > - {1, 1, CUBL, 0}, /* state undef */ > - > - /* Simple branches. */ > - {0, 0, 8, 9}, > - {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /= * state 10 bits displ */ > - {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state = word */ > - {1, 1, CSBL, 0}, > - > - /* blt no overflow branch. */ > - {1, 1, 8, 13}, > - {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* = state 10 bits displ */ > - {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state wo= rd */ > - {1, 1, CNOL, 0}, > - > - /* Emulated branches. */ > - {1, 1, 8, 17}, > - {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* = state 10 bits displ */ > - {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state wo= rd */ > - {1, 1, CNOL, 0} > + IMM_RANGE_INT16, /* signed 16-bit integer */ > + IMM_RANGE_INT20, /* signed 20-bit integer */ > + IMM_RANGE_REPETITION_COUNT, /* repetition count 1..16 */ > + IMM_RANGE_ROTATE_COUNT, /* rotation count 1..4 */ > }; >=20=20 > +/* Test that the value is representable in 16 bits, either signed or > + * unsigned */ > +#define MSP430_16_IN_RANGE(_v) ((_v) >=3D -((offsetT)1 << 15) && (_v) < = ((offsetT)1 << 16)) >=20=20 > -#define MAX_OP_LEN 256 > +/* Test that the value is representable in 15 bits, signed only */ > +#define MSP430_S16_IN_RANGE(_v) ((_v) >=3D -((offsetT)1 << 15) && (_v) <= ((offsetT)1 << 15)) >=20=20 > -struct mcu_type_s > +/* Test that the value is representable in 20 bits, either signed or > + * unsigned */ > +#define MSP430_20_IN_RANGE(_v) ((_v) >=3D -((offsetT)1 << 19) && (_v) < = ((offsetT)1 << 20)) > + > +/* Test that the value is representable in 10 bits, signed only */ > +#define MSP430_S10_IN_RANGE(_v) ((_v) >=3D -((offsetT)1 << 9) && (_v) < = ((offsetT)1 << 9)) > + > +/* Test whether the value is odd */ > +#define MSP430_ODD(_v) ((_v) & 1) > + > +static int > +valid_immediate (offsetT value, enum immediate_range_e imm_range) > { > - char * name; > - int isa; > - int mach; > -}; > + bfd_boolean valid; > + switch (imm_range) > + { > + case IMM_RANGE_INT16: > + valid =3D MSP430_16_IN_RANGE (value); > + if (!valid) > + as_bad (_("value %ld out of range for 16-bit immediate"), > + (long int) value); > + break; > + case IMM_RANGE_INT20: > + valid =3D MSP430_20_IN_RANGE (value); > + if (!valid) > + as_bad (_("value %ld out of range for 20-bit immediate"), > + (long int) value); > + break; > + case IMM_RANGE_REPETITION_COUNT: > + valid =3D value >=3D 1 && value <=3D 16; > + if (!valid) > + as_bad (_("value %ld not a repetition count (1..16)"), > + (long int) value); > + break; > + case IMM_RANGE_ROTATE_COUNT: > + valid =3D value >=3D 1 && value <=3D 4; > + if (!valid) > + as_bad (_("value %ld not a rotate count (1..4)"), (long int) value); > + break; > + default: > + gas_assert (0); > + valid =3D FALSE; > + } > + return valid; > +} >=20=20 > -#define MSP430_ISA_11 11 > -#define MSP430_ISA_110 110 > -#define MSP430_ISA_12 12 > -#define MSP430_ISA_13 13 > -#define MSP430_ISA_14 14 > -#define MSP430_ISA_15 15 > -#define MSP430_ISA_16 16 > -#define MSP430_ISA_21 21 > -#define MSP430_ISA_31 31 > -#define MSP430_ISA_32 32 > -#define MSP430_ISA_33 33 > -#define MSP430_ISA_41 41 > -#define MSP430_ISA_42 42 > -#define MSP430_ISA_43 43 > -#define MSP430_ISA_44 44 > - > -#define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BY= TE:BFD_RELOC_MSP430_16) > -#define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_1= 6_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL) > - > -static struct mcu_type_s mcu_types[] =3D > +/** List known silicon errata with a description of the problem (where > + * this can be found). Errata descriptions are available in PDF files > + * that can be found on the device-specific web page at TI. Errata > + * numbers are consistent across the product line. > + * > + * Note that not all documented errata are currently recognized by the > + * assembler. In fact, most are completely ignored. Future work... > + * > + * Legacy errata descriptions are from previous versions of > + * binutils. */ > +typedef enum msp430_errata_e > { > - {"msp1", MSP430_ISA_11, bfd_mach_msp11}, > - {"msp2", MSP430_ISA_14, bfd_mach_msp14}, > - {"msp430x110", MSP430_ISA_11, bfd_mach_msp11}, > - {"msp430x112", MSP430_ISA_11, bfd_mach_msp11}, > - {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110}, > - {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110}, > - {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110}, > - {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110}, > - {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110}, > - > - {"msp430x122", MSP430_ISA_12, bfd_mach_msp12}, > - {"msp430x123", MSP430_ISA_12, bfd_mach_msp12}, > - {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12}, > - {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12}, > - > - {"msp430x133", MSP430_ISA_13, bfd_mach_msp13}, > - {"msp430x135", MSP430_ISA_13, bfd_mach_msp13}, > - {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13}, > - {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13}, > - {"msp430x147", MSP430_ISA_14, bfd_mach_msp14}, > - {"msp430x148", MSP430_ISA_14, bfd_mach_msp14}, > - {"msp430x149", MSP430_ISA_14, bfd_mach_msp14}, > - > - {"msp430x155", MSP430_ISA_15, bfd_mach_msp15}, > - {"msp430x156", MSP430_ISA_15, bfd_mach_msp15}, > - {"msp430x157", MSP430_ISA_15, bfd_mach_msp15}, > - {"msp430x167", MSP430_ISA_16, bfd_mach_msp16}, > - {"msp430x168", MSP430_ISA_16, bfd_mach_msp16}, > - {"msp430x169", MSP430_ISA_16, bfd_mach_msp16}, > - {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16}, > - {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16}, > - {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16}, > - > - {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21}, > - {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21}, > - {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21}, > - {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21}, > -=20=20 > - {"msp430x311", MSP430_ISA_31, bfd_mach_msp31}, > - {"msp430x312", MSP430_ISA_31, bfd_mach_msp31}, > - {"msp430x313", MSP430_ISA_31, bfd_mach_msp31}, > - {"msp430x314", MSP430_ISA_31, bfd_mach_msp31}, > - {"msp430x315", MSP430_ISA_31, bfd_mach_msp31}, > - {"msp430x323", MSP430_ISA_32, bfd_mach_msp32}, > - {"msp430x325", MSP430_ISA_32, bfd_mach_msp32}, > - {"msp430x336", MSP430_ISA_33, bfd_mach_msp33}, > - {"msp430x337", MSP430_ISA_33, bfd_mach_msp33}, > - > - {"msp430x412", MSP430_ISA_41, bfd_mach_msp41}, > - {"msp430x413", MSP430_ISA_41, bfd_mach_msp41}, > - {"msp430x415", MSP430_ISA_41, bfd_mach_msp41}, > - {"msp430x417", MSP430_ISA_41, bfd_mach_msp41}, > - > - {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42}, > - {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42}, > - {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42}, > - > - {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42}, > - {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42}, > - {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42}, > - > - {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43}, > - {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43}, > - {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43}, > - > - {"msp430x435", MSP430_ISA_43, bfd_mach_msp43}, > - {"msp430x436", MSP430_ISA_43, bfd_mach_msp43}, > - {"msp430x437", MSP430_ISA_43, bfd_mach_msp43}, > - {"msp430x447", MSP430_ISA_44, bfd_mach_msp44}, > - {"msp430x448", MSP430_ISA_44, bfd_mach_msp44}, > - {"msp430x449", MSP430_ISA_44, bfd_mach_msp44}, > - > - {NULL, 0, 0} > + /* CPU4: PUSH #4, PUSH #8 > + * > + * The single operand instruction PUSH cannot use the internal > + * constants (CG) 4 and 8. The other internal constants (0, 1, 2, > + * =E2=80=931) can be used. The number of clock cycles is different: > + * > + * - PUSH #CG uses address mode 00, requiring 3 cycles, 1-word instruc= tion > + * - PUSH #4/#8 uses address mode 11, requiring 5 cycles, 2-word instr= uction > + * > + * Workaround: > + * - Assembler generate code not referencing constant generator > + */ > + ERRATUM_CPU4 =3D 4, > + > + /* CALL and PUSH with @SP+, @SP, and X(SP) uses the SP to calculate th= e address, then decrements it */ > + ERRATUM_CPU7 =3D 7, > + > + /* CPU8: Using odd values in the SP register > + * > + * The SP can be written with odd values. In the original CPU, an > + * odd SP value could be combined with an odd offset (for example, > + * mov. #value, 5(SP)). In the new CPU, the SP can be written with > + * an odd value, but the first time the SP is used, the LSB is > + * forced to 0. > + * > + * Workaround: > + * - Do not use odd values with the SP. > + */ > + ERRATUM_CPU8 =3D 8, /* UNHANDLED */ > + > + /* CPU11: Invalid status register after program counter access > + * > + * When addressing the program counter (PC) in register mode when > + * the PC is the destination, the Status Register (SR) may be > + * erroneous. The instructions BIS, BIC, and MOV do not affect SR > + * contents. Only CPU flags are affected. This bug does not apply to > + * LPMx control bits. > + * > + * Workaround: None > + */ > + ERRATUM_CPU11 =3D 11, /* UNHANDLED */ > + > + /* CPU12: CMP or BIT with PC destination > + * > + * Any instruction immediately following a CMP(.B) or BIT(.B) > + * instruction when the PC is the destination address using register > + * mode is ignored or erroneously executed. When the following > + * instruction is longer than one word, the second word is fetched > + * by the CPU and decoded as the instruction, leading to > + * unpredictable behavior. Affected source-addressing modes are > + * indexed and indirect addressing modes. > + * > + * Example: > + * cmp &200,PC > + * add #4,R8 > + * The add command is not executed. > + * > + * Workaround: > + * - Insert a NOP instruction after the BIT or CMP instruction. The > + * NOP is ignored, and program execution continues as expected. > + */ > + ERRATUM_CPU12 =3D 12, /* UNHANDLED */ > + > + /* CPU13: Arithmetic operations and the SR > + * > + * Performing arithmetic operations with the Status Register (SR) as > + * the destination address does not update the SR as intended. The > + * result in SR can be invalid, leading to erroneous low-power mode > + * entry. Arithmetic operations are defined as all instructions that > + * modify the SR flag bits (RRA, SUB, XOR, and ADD, for example). > + * > + * Workaround: None > + */ > + ERRATUM_CPU13 =3D 13, /* UNHANDLED */ > + > + /* CPU15: Modifying the Program Counter (PC) behaves differently > + * than in previous devices > + * > + * When using instructions with immediate or indirect addressing > + * mode to modify the PC, a different value compared to previous > + * devices must be added to get to the same destination. > + * > + * NOTE: The MOV instruction is not affected > + * > + * Example: Previous device (MSP430F4619) > + * label_1 ADD.W #Branch1-label_1-4h,PC > + * MSP430F5438: > + * label_1 ADD.W #Branch1-label_1-2h,PC > + * > + * Workaround: > + * - Additional NOP after the PC-modifying instruction; or > + * - Change the offset value in software > + */ > + ERRATUM_CPU15 =3D 15, /* UNHANDLED */ > + > + /* CPU16 Indexed addressing with instructions calla, mova, and bra > + * > + * With indexed addressing mode and instructions calla, mova, and bra,= it is not possible > + * to reach memory above 64k if the register content is < 64k. > + * Example: Assume R5 =3D FFFEh. The instruction calla 0004h(R5) resul= ts in a 20-bit call > + * of address 0002h instead of 10002h. > + * > + * Workaround: > + * - Use different addressing mode to reach memory above 64k. > + * - First use adda [index],[Rx] to calculate address in upper memory = and then use > + * calla [Rx]. > + */ > + ERRATUM_CPU16 =3D 16, /* UNHANDLED */ > + > + /* CPU18: LPM instruction can corrupt PC/SR registers > + * > + * The PC and SR registers have the potential to be corrupted when: > + * - An instruction using register, absolute, indexed, indirect, > + * indirect auto-increment, or symbolic mode is used to set the > + * LPM bits (for example, BIS &xyh, SR). > + * and > + * - This instruction is followed by a CALL or CALLA instruction. > + * > + * Upon servicing an interrupt service routine, the program counter > + * (PC) is pushed twice onto the stack instead of the correct > + * operation where the PC, then the SR registers are pushed onto the > + * stack. This corrupts the SR and possibly the PC on RETI from the > + * ISR. > + * > + * Workaround: > + * - Insert a NOP or __no_operation() intrinsic function between the > + * instruction to enter low-power mode and the CALL or CALLA > + * instruction. > + */ > + ERRATUM_CPU18 =3D 18, /* UNHANDLED */ > + > + /* CPU19: CPUOFF can change register values > + * > + * If a CPUOFF command is followed by an instruction with an > + * indirect addressed operand (for example, mov @R8, R9, and RET), > + * an unintentional register-read operation can occur during the > + * wakeup of the CPU. If the unintentional read occurs to a > + * read-sensitive register (for example, UCB0RXBUF or TAIV), which > + * changes its value or the value of other registers (IFGs), the bug > + * leads to lost interrupts or wrong register read values. > + * > + * Workaround: > + * - Insert a NOP instruction after each CPUOFF instruction. > + */ > + ERRATUM_CPU19 =3D 19, /* UNHANDLED */ > + > + /* CPU20: An unexpected Vacant Memory Access Flag (VMAIFG) can be > + * triggered due to the CPU autoincrement of the MAB + 2 > + * outside the range of a valid memory block. > + * > + * The VMAIFG is triggered if a PC-modifying instruction (for > + * example, ret, push, call, pop, jmp, br) is fetched from the last > + * address of a section of memory (for example, flash or RAM) that > + * is not contiguous to a higher valid section on the memory map. > + * > + * Workaround: > + * - If code is affected, edit the linker command file to make the > + * last four bytes of affected memory sections unavailable. > + */ > + ERRATUM_CPU20 =3D 20, /* UNHANDLED */ > + > + /* NO DESCRIPTION */ > + ERRATUM_CPU21 =3D 21, /* UNHANDLED */ > + > + /* NO DESCRIPTION */ > + ERRATUM_CPU22 =3D 22, /* UNHANDLED */ > + > + /* NO DESCRIPTION */ > + ERRATUM_CPU23 =3D 23, /* UNHANDLED */ > + > + /* CPU24: Program counter corruption following entry into low power mo= de > + * > + * The program counter is corrupted when an interrupt event occurs > + * in the time between (and including) one cycle before and one > + * cycle after the CPUOFF bit is set in the status register. This > + * failure occurs when the BIS instruction is followed by a CALL or > + * CALLA instruction using the following addressing modes: > + * > + * - BIS &, SR > + * CALLA indir, indir autoinc, reg > + * > + * - BIS INDEX, SR > + * CALLA indir, indir autoinc, reg > + * > + * - BIS reg, SR > + * CALLA reg, indir, indir autoinc > + * > + * Due to the instruction emulation, the EINT instruction, as well > + * as the __enable_interrupts() and possibly the __bis_SR_register() > + * intrinsic functions are affected. > + * > + * Workaround: > + * - Insert a NOP instruction or __no_operation() intrinsic function > + * call between the BIS and CALL or CALLA instructions. > + */ > + ERRATUM_CPU24 =3D 24, /* UNHANDLED */ > + > + /* CPU25: DMA transfer does not execute during low power mode > + * > + * If the following instruction sequence is used ([] denotes an > + * addressing mode): > + *=20 > + * BIS [register|index|absolute|symbolic],SR > + * CALLA [register] > + * > + * ...to enter a low power mode, AND the DMARMWDIS bit is set then > + * DMA transfers will be blocked for the duration of the low power > + * mode. > + * > + * Workaround: > + * 1. Insert a NOP instruction or __no_operation() intrinsic > + * function call between the BIS and CALLA instructions ... OR > + * ... > + * 2. Temporarily clear the DMARMWDIS bit when entering low power > + * mode > + */ > + ERRATUM_CPU25 =3D 25, /* UNHANDLED */ > + > + /* CPU26: CALL SP does not behave as expected > + * > + * When the intention is to execute code from the stack, a CALL SP > + * instruction skips the first piece of data (instruction) on the > + * stack. The second piece of data at SP + 2 is used as the first > + * executable instruction. > + * > + * Workaround: > + * - Write the op code for a NOP as the first instruction on the > + * stack. Begin the intended subroutine at address SP + 2. > + */ > + ERRATUM_CPU26 =3D 26, /* UNHANDLED */ > + > + /* CPU27: Program Counter (PC) is corrupted during the context save > + * of a nested interrupt > + * > + * When a low-power mode is entered within an interrupt service > + * routine that has enabled nested interrupts (by setting the GIE > + * bit), and the instruction that sets the low-power mode is > + * directly followed by a RETI instruction, an incorrect value of PC > + * + 2 is pushed to the stack during the context save. Hence, the > + * RETI instruction is not executed on return from the nested > + * interrupt, and the PC becomes corrupted. > + * > + * Workaround: > + * - Insert a NOP or __no_operation() intrinsic function between the > + * instruction that sets the lower power mode and the RETI > + * instruction. > + */ > + ERRATUM_CPU27 =3D 27, /* UNHANDLED */ > + > + /* CPU28: PC is corrupted when using certain extended addressing > + * mode combinations > + * > + * An extended memory instruction that modifies the program counter > + * executes incorrectly when preceded by an extended memory > + * write-back instruction under the following conditions: > + * > + * - First instruction: > + * 2-operand instruction, extended mode using (register,index), > + * (register,absolute), or (register,symbolic) addressing modes > + * - Second instruction: > + * 2-operand instruction, extended mode using the (indirect,PC), > + * (indirect auto-increment,PC), or (indexed [with ind 0], PC) > + * addressing modes > + * > + * Example: > + * BISX.A R6,&AABCD > + * ANDX.A @R4+,PC > + * > + * Workaround: > + * - Insert a NOP or a __no_operation() intrinsic function between > + * the two instructions. > + * or > + * - Do not use an extended memory instruction to modify the PC. > + */ > + ERRATUM_CPU28 =3D 28, /* UNHANDLED */ > + > + /* CPU29: Using a certain instruction sequence to enter low-power > + * mode(s) affects the instruction width of the first > + * instruction in an NMI ISR > + * > + * If there is a pending NMI request when the CPU enters a low-power > + * mode (LPMx) using an instruction of Indexed source addressing > + * mode, and that instruction is followed by a 20-bit wide > + * instruction of Register source and Destination addressing modes, > + * the first instruction of the ISR is executed as a 20-bit wide > + * instruction. > + * > + * Example: > + * main: > + * ... > + * MOV.W [indexed],SR ; Enter LPMx > + * MOVX.A [register],[register] ; 20-bit wide instruction > + * ... > + * ISR_start: > + * MOV.B [indexed],[register] ; ERROR - Executed as a 20-b= it instruction! > + * > + * Note: [ ] indicates addressing mode > + * > + * Workaround: > + * - Insert a NOP or a __no_operation() intrinsic function following > + * the instruction that enters the LPMx using indexed addressing > + * mode. > + * or > + * - Use a NOP or a __no_operation() intrinsic function as first > + * instruction in the ISR. > + * or > + * - Do not use the indexed mode to enter LPMx. > + */ > + ERRATUM_CPU29 =3D 29, /* UNHANDLED */ > + > + /* CPU30: ADDA, SUBA, CMPA [immediate],PC behave as if immediate > + * value were offset by -2 > + * > + * The extended address instructions ADDA, SUBA, and CMPA in > + * immediate addressing mode are represented by 4 bytes of opcode > + * (see the MSP430F5xx Family User's Guide (SLAU208) for more > + * details). In cases where the program counter (PC) is used as the > + * destination register, only 2 bytes of the current instruction's > + * 4-byte opcode are accounted for in the PC value. The resulting > + * operation executes as if the immediate value were offset by a > + * value of -2. > + * > + * Example: > + * Ideal: ADDA #Immediate-4, PC > + * ...is equivalent to... > + * Actual: ADDA #Immediate-2, PC > + * NOTE: The MOV instruction is not affected. > + * > + * Workaround: > + * - Modify immediate value in software to account for the offset of 2. > + * or > + * - Use extended 20-bit instructions (addx.a, subx.a, cmpx.a) instead. > + */ > + ERRATUM_CPU30 =3D 30, /* UNHANDLED */ > + > + /* CPU31: Instruction PUSHX.A @SP+ corrupts stack pointer > + * > + * When the instruction PUSHX.A is executed using the indirect > + * auto-increment mode with the stack pointer (SP) as the source > + * register [PUSHX.A @SP+] the SP is consequently corrupted. Instead > + * of decrementing the value of the SP by four, the value of the SP > + * is replaced with the data pointed to by the SP previous to the > + * PUSHX.A instruction execution. > + * > + * Workaround: > + * None. The compiler must not generate a PUSHX.A instruction that > + * involves the SP. > + */ > + ERRATUM_CPU31 =3D 31, /* UNHANDLED */ > + > + /* CPU32: CALLA PC executes incorrectly > + * > + * When the instruction CALLA PC is executed, the program counter > + * (PC) that is pushed onto the stack during the context save is > + * incorrectly offset by a value of -2. > + *=20 > + * Workaround: > + * None. The compiler must not generate a CALLA PC instruction. > + */ > + ERRATUM_CPU32 =3D 32, /* UNHANDLED */ > + > + /* CPU33: Instruction sequence PUSH &addr; CALLA x(SP); generates > + * incorrect access for CALLA > + * > + * When the Stack Pointer (SP) is used as the destination register > + * in the CALLA index(Rdst) instruction and is preceded by a PUSH or > + * PUSHX instruction in any of the following addressing modes: > + * Absolute, Symbolic, Indexed, Indirect register or Indirect auto > + * increment, the "index" of the CALLA instruction is not sign > + * extended to 20-bits and is always treated as a positive > + * value. This causes the Program Counter to be set to a wrong > + * address location when the index of the CALLA instruction > + * represents a negative offset. > + * > + * Note: > + * 1. This erratum only applies when the instruction sequence is: > + * PUSH or PUSHX followed by CALLA index(SP) > + * 2. This erratum does not apply if the PUSH or PUSHX instruction > + * is used in the Register or Immediate addressing mode > + * 3. This erratum only applies when SP is used as the destination > + * register in the CALLA index(Rdst) instruction > + *=20=20=20=20 > + * Workaround: > + * Place a "NOP" instruction in between the PUSH or PUSHX and the > + * CALLA index(SP) instructions. > + */ > + ERRATUM_CPU33 =3D 33, /* UNHANDLED */ > + > + /* CPU34: CPU may be halted if a conditional jump is followed by a > + * rotate PC instruction > + * > + * If a conditional jump instruction (JZ, JNZ, JC, JNC, JN, JGE, JL) > + * is followed by an Address Rotate instruction on the PC (RRCM, > + * RRAM, RLAM, RRUM) and the jump is not performed, the CPU is > + * halted. > + * > + * Workaround: > + * Insert a NOP between the conditional jump and the rotate PC > + * instructions. > + */ > + ERRATUM_CPU34 =3D 34, /* UNHANDLED */ > + > + /* CPU35: Instruction BIT.B @Rx,PC uses the wrong PC value > + * > + * The BIT(.B/.W) instruction in indirect register addressing mode > + * uses the wrong PC value. This instruction is represented by 2 > + * bytes of opcode. If the Program Counter (PC) is used as the > + * destination register, the 2 opcode bytes of the current BIT > + * instruction are not accounted for. The resulting operation > + * executes the instruction using the wrong PC value and this > + * affects the results in the Status Register (SR). > + * > + * Workaround: None > + */ > + ERRATUM_CPU35 =3D 35, /* UNHANDLED */ > + > + /* CPU40: PC is corrupted when executing jump/conditional jump > + * instruction that is followed by instruction with PC as > + * destination register or a data section > + * > + * If the value at the memory location immediately following a > + * jump/conditional jump instruction is 0X40h or 0X50h (where X =3D > + * don't care), which could either be an instruction opcode (for > + * instructions like RRCM, RRAM, RLAM, RRUM) with PC as destination > + * register or a data section (const data in flash memory or data > + * variable in RAM), then the PC value gets auto-incremented by 2 > + * after the jump instruction is executed; thus branching to a wrong > + * address location in code and leading to wrong program execution. > + * > + * For example, a conditional jump instruction followed by data > + * section (0140h). > + *=20 > + * @0x8012 Loop DEC.W R6 > + * @0x8014 DEC.W R7 > + * @0x8016 JNZ Loop > + * @0x8018 Value1 DW 0140h > + * > + * Workaround: > + * - In assembly, insert a NOP between the jump/conditional jump > + * instruction and program code with instruction that contains PC > + * as destination register or the data section. > + */ > + ERRATUM_CPU40 =3D 40, /* UNHANDLED */ > +} msp430_errata_e; > + > +/* sed -e '1,/enum msp430_errata/d' -e '/^\}/,$d' tc-msp430.c \ > + | grep '^ *ERRATUM_*' \ > + | cut -d=3D -f1 \ > + | sed 's@ *$@,@' */ > +static const int recognized_errata[] =3D { > + ERRATUM_CPU4, > + ERRATUM_CPU7, > + ERRATUM_CPU8, > + ERRATUM_CPU11, > + ERRATUM_CPU12, > + ERRATUM_CPU13, > + ERRATUM_CPU15, > + ERRATUM_CPU16, > + ERRATUM_CPU18, > + ERRATUM_CPU19, > + ERRATUM_CPU20, > + ERRATUM_CPU21, > + ERRATUM_CPU22, > + ERRATUM_CPU23, > + ERRATUM_CPU24, > + ERRATUM_CPU25, > + ERRATUM_CPU26, > + ERRATUM_CPU27, > + ERRATUM_CPU28, > + ERRATUM_CPU29, > + ERRATUM_CPU30, > + ERRATUM_CPU31, > + ERRATUM_CPU32, > + ERRATUM_CPU33, > + ERRATUM_CPU34, > + ERRATUM_CPU35, > + ERRATUM_CPU40, > }; >=20=20 > - > -static struct mcu_type_s default_mcu =3D > - { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 }; > - > -static struct mcu_type_s * msp430_mcu =3D & default_mcu; > +static int msp430_cpu =3D MSP430_CPU_MSP430; > +static int msp430_mpy =3D MSP430_MPY_NONE; > +static int *msp430_errata =3D 0; >=20=20 > /* Profiling capability: > It is a performance hit to use gcc's profiling approach for this tiny= target. > @@ -441,89 +730,80 @@ pow2value (int y) > return n =3D=3D 1; > } >=20=20 > -/* Parse ordinary expression. */ > - > +/* Invoke read routines to parse anordinary expression. > + * > + * s points to a standalone operand. op is where to store the > + * resulting expression. The call returns a pointer to the suffix of > + * s that remained unparsed. > + * > + * Note that the underlying GAS parsing code may assume that it can > + * modify the contents of the buffer. */ > static char * > -parse_exp (char * s, expressionS * op) > +parse_exp (char *s, expressionS * op) > { > + char *in_save =3D input_line_pointer; > input_line_pointer =3D s; > expression (op); > + s =3D input_line_pointer; > if (op->X_op =3D=3D O_absent) > as_bad (_("missing operand")); > - return input_line_pointer; > -} > - > - > -/* Delete spaces from s: X ( r 1 2) =3D> X(r12). */ > - > -static void > -del_spaces (char * s) > -{ > - while (*s) > - { > - if (ISSPACE (*s)) > - { > - char *m =3D s + 1; > - > - while (ISSPACE (*m) && *m) > - m++; > - memmove (s, m, strlen (m) + 1); > - } > - else > - s++; > - } > -} > - > -static inline char * > -skip_space (char * s) > -{ > - while (ISSPACE (*s)) > - ++s; > + input_line_pointer =3D in_save; > return s; > } >=20=20 > -/* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" = */ > - > +/* Extract one operand into a dynamically allocated mutable buffer. > + * > + * The operand begins at input_line_pointer, and is terminated by > + * comma (','), semicolon (';'), or newline ('\n'). Leading and > + * interior whitespace is removed. If the terminating character is > + * comma (','), it is consumed (but not part of the operand). */ > static char * > -extract_operand (char * from, char * to, int limit) > +get_operand (void) > { > - int size =3D 0; > + char *sp =3D input_line_pointer; > + char *end_ilp; > + char *dest; > + char *dp; > + int operand_length =3D 0; >=20=20 > - /* Drop leading whitespace. */ > - from =3D skip_space (from); > - > - while (size < limit && *from) > + while (*sp && ',' !=3D *sp && ';' !=3D *sp && '\n' !=3D *sp) > { > - *(to + size) =3D *from; > - if (*from =3D=3D ',' || *from =3D=3D ';' || *from =3D=3D '\n') > - break; > - from++; > - size++; > + if (!ISSPACE (*sp)) > + ++operand_length; > + ++sp; > } > + end_ilp =3D sp; >=20=20 > - *(to + size) =3D 0; > - del_spaces (to); > - > - from++; > - > - return from; > + dp =3D dest =3D xmalloc (operand_length + 1); > + sp =3D input_line_pointer; > + while (0 < operand_length) > + { > + if (!ISSPACE (*sp)) > + { > + *dp++ =3D *sp; > + --operand_length; > + } > + ++sp; > + } > + *dp =3D 0; > + input_line_pointer =3D end_ilp; > + if (',' =3D=3D *input_line_pointer) > + ++input_line_pointer; > + return dest; > } >=20=20 > static void > msp430_profiler (int dummy ATTRIBUTE_UNUSED) > { > - char buffer[1024]; > - char f[32]; > - char * str =3D buffer; > - char * flags =3D f; > - int p_flags =3D 0; > - char * halt; > - int ops =3D 0; > - int left; > - char * s; > - segT seg; > - int subseg; > - char * end =3D 0; > + char *flag_token =3D 0; > + char *flags; > + int p_flags =3D 0; > + int ops =3D 0; > + int left; > + char *s; > + segT seg; > + int subseg; > + char *end =3D 0; > expressionS exp; > expressionS exp1; >=20=20 > @@ -549,8 +829,7 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED) > return; > } >=20=20 > - input_line_pointer =3D extract_operand (input_line_pointer, flags, 32); > - > + flags =3D flag_token =3D get_operand (); > while (*flags) > { > switch (*flags) > @@ -608,18 +887,20 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED) > } > flags++; > } > + xfree (flag_token); >=20=20 > if (p_flags > - && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY > - | MSP430_PROFILER_FLAG_EXIT)) > - || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART > - | MSP430_PROFILER_FLAG_PROLEND > - | MSP430_PROFILER_FLAG_EPISTART > - | MSP430_PROFILER_FLAG_EPIEND)) > - || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT > - | MSP430_PROFILER_FLAG_FINISECT)))) > + && (!pow2value (p_flags & (MSP430_PROFILER_FLAG_ENTRY > + | MSP430_PROFILER_FLAG_EXIT)) > + || !pow2value (p_flags & (MSP430_PROFILER_FLAG_PROLSTART > + | MSP430_PROFILER_FLAG_PROLEND > + | MSP430_PROFILER_FLAG_EPISTART > + | MSP430_PROFILER_FLAG_EPIEND)) > + || !pow2value (p_flags & (MSP430_PROFILER_FLAG_INITSECT > + | MSP430_PROFILER_FLAG_FINISECT)))) > { > - as_bad (_("ambiguous flags combination - '.profiler' directive ign= ored.")); > + as_bad (_ > + ("ambiguous flags combination - '.profiler' directive ignored.")); > input_line_pointer =3D end; > return; > } > @@ -650,136 +931,242 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED) > obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0); >=20=20 > /* Save flags. */ > - emit_expr (& exp, 2); > + emit_expr (&exp, 2); >=20=20 > /* Save label value. */ > - emit_expr (& exp1, 2); > + emit_expr (&exp1, 2); >=20=20 > while (ops--) > { > /* Now get profiling info. */ > - halt =3D extract_operand (input_line_pointer, str, 1024); > + char *halt =3D get_operand (); > /* Process like ".word xxx" directive. */ > - parse_exp (str, & exp); > - emit_expr (& exp, 2); > - input_line_pointer =3D halt; > + parse_exp (halt, &exp); > + emit_expr (&exp, 2); > + xfree (halt); > } >=20=20 > /* Fill the rest with zeros. */ > exp.X_op =3D O_constant; > exp.X_add_number =3D 0; > while (left--) > - emit_expr (& exp, 2); > + emit_expr (&exp, 2); >=20=20 > /* Return to current section. */ > subseg_set (seg, subseg); > } >=20=20 > -static char * > -extract_word (char * from, char * to, int limit) > +struct tag_value_pair_t > { > - char *op_end; > - int size =3D 0; > + const char *tag; > + unsigned long value; > +}; > + > +static const struct tag_value_pair_t cpu_tag_value_map[] =3D { > + {"430", MSP430_CPU_MSP430}, > + {"430x", MSP430_CPU_MSP430X}, > + {"430xv2", MSP430_CPU_MSP430XV2}, > + {0, 0} > +}; >=20=20 > - /* Drop leading whitespace. */ > - from =3D skip_space (from); > - *to =3D 0; > +static const struct tag_value_pair_t mpy_tag_value_map[] =3D { > + {"none", MSP430_MPY_NONE}, > + {"16", MSP430_MPY_16}, > + {"16se", MSP430_MPY_16SE}, > + {"32", MSP430_MPY_32}, > + {"32dw", MSP430_MPY_32DW}, > + {0, 0} > +}; >=20=20 > - /* Find the op code end. */ > - for (op_end =3D from; *op_end !=3D 0 && is_part_of_name (*op_end);) > +static const struct tag_value_pair_t * > +find_pair_by_tag (const char *tag, const struct tag_value_pair_t *map) > +{ > + while (map->tag) > { > - to[size++] =3D *op_end++; > - if (size + 1 >=3D limit) > - break; > + if (0 =3D=3D strcmp (tag, map->tag)) > + return map; > + ++map; > + } > + return 0; > +} > + > +#if 0 > +static const struct tag_value_pair_t * > +find_pair_by_value (unsigned long value, const struct tag_value_pair_t *= map) > +{ > + while (map->tag) > + { > + if (map->value =3D=3D value) > + return map; > + ++map; > } > + return 0; > +} > +#endif >=20=20 > - to[size] =3D 0; > - return op_end; > +enum > +{ > + OPTION_MMCU =3D 'm', > + OPTION_CPU =3D OPTION_MD_BASE + 0, > + OPTION_MPY, > + OPTION_ERRATA, > +}; > + > +static int > +erratum_applies (int erratum) > +{ > + if (!msp430_errata) > + if (ERRATUM_CPU4 =3D=3D erratum) > + return msp430_cpu < MSP430_CPU_MSP430X; > + return 0; > +} > + > +static int > +cpu_from_text (const char *text) > +{ > + const struct tag_value_pair_t *mp =3D > + find_pair_by_tag (text, cpu_tag_value_map); > + if (!mp) > + as_fatal (_("unrecognized cpu type %s"), text); > + return mp->value; > } >=20=20 > -#define OPTION_MMCU 'm' > -#define OPTION_RELAX 'Q' > -#define OPTION_POLYMORPHS 'P' > +static int > +mpy_from_text (const char *text) > +{ > + const struct tag_value_pair_t *mp =3D > + find_pair_by_tag (text, mpy_tag_value_map); > + if (!mp) > + as_fatal (_("unrecognized hardware multiplier type %s"), text); > + return mp->value; > +} >=20=20 > static void > -msp430_set_arch (int dummy ATTRIBUTE_UNUSED) > +set_arch_mach (int cpu, int mpy ATTRIBUTE_UNUSED) > +{ > + unsigned long mach =3D bfd_mach_msp430; > + if (MSP430_CPU_MSP430X <=3D cpu) > + mach =3D bfd_mach_msp430x; > + bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach); > +} > + > +/* Like get_symbol_end, but accepts sequences that start with > + * digits and doesn't strip out name ends */ > +static char > +get_token_end (void) > { > - char *str =3D (char *) alloca (32); /* 32 for good measure. */ > + char c; >=20=20 > - input_line_pointer =3D extract_word (input_line_pointer, str, 32); > + while (is_part_of_name (c =3D *input_line_pointer++)) > + ; > + *--input_line_pointer =3D 0; > + return (c); > +} >=20=20 > - md_parse_option (OPTION_MMCU, str); > - bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach); > +static void > +msp430_set_mcu (int dummy ATTRIBUTE_UNUSED) > +{ > + SKIP_WHITESPACE (); > + if (!is_end_of_line[(unsigned char) *input_line_pointer]) > + { > + char *tag_start =3D input_line_pointer; > + int ch =3D get_token_end (); > + md_parse_option (OPTION_MMCU, tag_start); > + *input_line_pointer =3D ch; > + demand_empty_rest_of_line (); > + } > + else > + as_bad (_("missing value for arch")); > } >=20=20 > static void > -show_mcu_list (FILE * stream) > +msp430_set (int option) > { > - int i; > + char *tag =3D 0; > + > + SKIP_WHITESPACE (); > + if (!is_end_of_line[(unsigned char) *input_line_pointer]) > + { > + char *tag_start =3D input_line_pointer; > + char e =3D get_token_end (); > + int tag_len =3D input_line_pointer + 1 - tag_start; > + tag =3D (char *) xmalloc (tag_len); > + memcpy (tag, tag_start, tag_len); > + *input_line_pointer =3D e; > + demand_empty_rest_of_line (); > + } >=20=20 > - fprintf (stream, _("Known MCU names:\n")); > + switch (option) > + { > + case OPTION_CPU: > + if (!tag) > + as_bad (_("missing value for cpu")); > + msp430_cpu =3D cpu_from_text (tag); > + break; > + case OPTION_MPY: > + if (!tag) > + as_bad (_("missing value for mpy")); > + msp430_mpy =3D mpy_from_text (tag); > + break; > + default: > + abort (); > + } >=20=20 > - for (i =3D 0; mcu_types[i].name; i++) > - fprintf (stream, _("\t %s\n"), mcu_types[i].name); > + set_arch_mach (msp430_cpu, msp430_mpy); >=20=20 > - fprintf (stream, "\n"); > } >=20=20 > -int > -md_parse_option (int c, char * arg) > +static void > +msp430_set_errata (int dummy ATTRIBUTE_UNUSED) > { > - int i; > +} >=20=20 > +int > +md_parse_option (int c, char *arg) > +{ > switch (c) > { > case OPTION_MMCU: > - for (i =3D 0; mcu_types[i].name; ++i) > - if (strcmp (mcu_types[i].name, arg) =3D=3D 0) > - break; > - > - if (!mcu_types[i].name) > - { > - show_mcu_list (stderr); > - as_fatal (_("unknown MCU: %s\n"), arg); > - } > - > - if (msp430_mcu =3D=3D &default_mcu || msp430_mcu->mach =3D=3D mcu_= types[i].mach) > - msp430_mcu =3D &mcu_types[i]; > - else > - as_fatal (_("redefinition of mcu type %s' to %s'"), > - msp430_mcu->name, mcu_types[i].name); > + /* TODO: warn about unrecognized mcu option */ > return 1; > break; > -=20=20=20=20=20=20 > - case OPTION_RELAX: > - msp430_enable_relax =3D 1;=20 > + > + case OPTION_CPU: > + msp430_cpu =3D cpu_from_text (arg); > return 1; > break; > -=20=20=20=20=20=20 > - case OPTION_POLYMORPHS: > - msp430_enable_polys =3D 1; > + > + case OPTION_MPY: > + msp430_mpy =3D mpy_from_text (arg); > return 1; > break; > + > + case OPTION_ERRATA: > + break; > } >=20=20 > return 0; > } >=20=20 > +static void msp430_repeat_insn (int dummy ATTRIBUTE_UNUSED); >=20=20 > -const pseudo_typeS md_pseudo_table[] =3D > -{ > - {"arch", msp430_set_arch, 0}, > +const pseudo_typeS md_pseudo_table[] =3D { > + {"arch", msp430_set_mcu, 0}, > {"profiler", msp430_profiler, 0}, > + {"rpt", msp430_repeat_insn, 0}, > + {"cpu", msp430_set, OPTION_CPU}, > + {"mpy", msp430_set, OPTION_MPY}, > + {"errata", msp430_set_errata, 0}, > {NULL, NULL, 0} > }; >=20=20 > const char *md_shortopts =3D "m:"; >=20=20 > -struct option md_longopts[] =3D > -{ > +struct option md_longopts[] =3D { > {"mmcu", required_argument, NULL, OPTION_MMCU}, > - {"mP", no_argument, NULL, OPTION_POLYMORPHS}, > - {"mQ", no_argument, NULL, OPTION_RELAX}, > + {"mcpu", required_argument, NULL, OPTION_CPU}, > + {"mmpy", required_argument, NULL, OPTION_MPY}, > + {"merrata", required_argument, NULL, OPTION_ERRATA}, > {NULL, no_argument, NULL, 0} > }; >=20=20 > @@ -789,60 +1176,31 @@ void > md_show_usage (FILE * stream) > { > fprintf (stream, > - _("MSP430 options:\n" > - " -mmcu=3D[msp430-name] select microcontroller type\n" > - " msp430x110 msp430x112\n" > - " msp430x1101 msp430x1111\n" > - " msp430x1121 msp430x1122 msp430x1132\n" > - " msp430x122 msp430x123\n" > - " msp430x1222 msp430x1232\n" > - " msp430x133 msp430x135\n" > - " msp430x1331 msp430x1351\n" > - " msp430x147 msp430x148 msp430x149\n" > - " msp430x155 msp430x156 msp430x157\n" > - " msp430x167 msp430x168 msp430x169\n" > - " msp430x1610 msp430x1611 msp430x1612\n" > - " msp430x311 msp430x312 msp430x313 msp430x314 = msp430x315\n" > - " msp430x323 msp430x325\n" > - " msp430x336 msp430x337\n" > - " msp430x412 msp430x413 msp430x415 msp430x417\= n" > - " msp430xE423 msp430xE425 msp430E427\n" > - " msp430xW423 msp430xW425 msp430W427\n" > - " msp430xG437 msp430xG438 msp430G439\n" > - " msp430x435 msp430x436 msp430x437\n" > - " msp430x447 msp430x448 msp430x449\n")); > - fprintf (stream, > - _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n" > - " -mP - enable polymorph instructions\n")); > - > - show_mcu_list (stream); > + _("MSP430 as-specific options:\n" > + " -mmcu=3D[msp430-name] select microcontroller type (ignored)\n" > + " -mcpu=3D{430,430x,430xv2} select cpu model\n" > + " -mmpy=3D{none,16,16se,32,32dw} select hardware multiplier type\= n" > + " -merrata=3D[cpuX,...] list relevant errata\n")); > } >=20=20 > symbolS * > -md_undefined_symbol (char * name ATTRIBUTE_UNUSED) > -{ > - return 0; > -} > - > -static char * > -extract_cmd (char * from, char * to, int limit) > +md_undefined_symbol (char *name) > { > - int size =3D 0; > - > - while (*from && ! ISSPACE (*from) && *from !=3D '.' && limit > size) > + if ('r' =3D=3D TOLOWER (name[0]) && ISDIGIT (name[1])) > { > - *(to + size) =3D *from; > - from++; > - size++; > - } > + char *rp =3D name + 1; > + unsigned int regno =3D *rp++ - '0'; >=20=20 > - *(to + size) =3D 0; > - > - return from; > + if (ISDIGIT (*rp)) > + regno =3D (regno * 10) + *rp++ - '0'; > + if (0 =3D=3D *rp && regno <=3D REGNO_MAX) > + return msp430_register_table[regno]; > + } > + return 0; > } >=20=20 > char * > -md_atof (int type, char * litP, int * sizeP) > +md_atof (int type, char *litP, int *sizeP) > { > return ieee_md_atof (type, litP, sizeP, FALSE); > } > @@ -850,564 +1208,626 @@ md_atof (int type, char * litP, int * sizeP) > void > md_begin (void) > { > - struct msp430_opcode_s * opcode; > + int regno; > + struct msp430_opcode_s const *opcode; > msp430_hash =3D hash_new (); >=20=20 > for (opcode =3D msp430_opcodes; opcode->name; opcode++) > hash_insert (msp430_hash, opcode->name, (char *) opcode); > + for (regno =3D REGNO_MIN; regno <=3D REGNO_MAX; ++regno) > + { > + char regname[4]; > + snprintf (regname, sizeof (regname), "r%u", regno); > + msp430_register_table[regno] =3D > + symbol_create (regname, reg_section, regno, &zero_address_frag); > + } >=20=20 > - bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach); > + set_arch_mach (msp430_cpu, msp430_mpy); > } >=20=20 > -static int > -check_reg (char * t) > +static void > +msp430_address_substitute_CG (struct msp430_opcode_s const *opcode, > + struct msp430_operand_s *op) > { > - /* If this is a reg numb, str 't' must be a number from 0 - 15. */ > - > - if (strlen (t) > 2 && *(t + 2) !=3D '+') > - return 1; > - > - while (*t) > + offsetT supported_cg2; > + > + /* Substitute CG2 if applicable. */ > + if (!OP_HAS_IMMEDIATE (*op) > + || (op->exp.X_op !=3D O_constant && op->exp.X_op !=3D O_big)) > + return; > + if (op->am !=3D AMs_Immediate || op->reg !=3D REGNO_PC) /* not #N */ > + return; > +=20=20 > + if (opcode_variant (opcode) =3D=3D V_CG2_TWO) > + supported_cg2 =3D 2; > + else > + supported_cg2 =3D 0; > + if (op->exp.X_add_number =3D=3D supported_cg2) > { > - if ((*t < '0' || *t > '9') && *t !=3D '+') > - break; > - t++; > + op->reg =3D REGNO_CG2; > + op->am =3D AM_Register; > + op->ol =3D 0; > } > - > - if (*t) > - return 1; > - > - return 0; > } >=20=20 > +static void > +msp430_substitute_CG (struct msp430_operand_s *op, opwidth_t op_width, > + int workaround) > +{ > + /* Substitute register mode with a constant generator if applicable. = */ > + if (!OP_HAS_IMMEDIATE (*op) > + || (op->exp.X_op !=3D O_constant && op->exp.X_op !=3D O_big)) > + return; > + if (op->am !=3D AMs_Immediate || op->reg !=3D REGNO_PC) /* not #N */ > + return; > + offsetT x =3D op->exp.X_add_number; > + > + if ((BYTE_OP =3D=3D op_width && MASK_8 (x) =3D=3D MASK_8 (-1)) > + || (WORD_OP =3D=3D op_width && MASK_16 (x) =3D=3D MASK_16 (-1)) > + || (ADDR_OP =3D=3D op_width && MASK_20 (x) =3D=3D MASK_20 (-1))) > + x =3D -1; > + > + if (x =3D=3D 0) > + { > + op->reg =3D REGNO_CG2; > + op->am =3D 0; /* AM_Register */ > + op->ol =3D 0; > + } > + else if (x =3D=3D 1) > + { > + op->reg =3D REGNO_CG2; > + op->am =3D 1; /* AM_Indexed */ > + op->ol =3D 0; > + } > + else if (x =3D=3D 2) > + { > + op->reg =3D REGNO_CG2; > + op->am =3D 2; /* AMs_IndirectRegister */ > + op->ol =3D 0; > + } > + else if (x =3D=3D -1) > + { > + op->reg =3D REGNO_CG2; > + op->am =3D 3; /* AMs_IndirectAutoIncrement */ > + op->ol =3D 0; > + } > + else if (x =3D=3D 4 && !workaround) > + { > + op->reg =3D REGNO_CG1; > + op->am =3D 2; /* AMs_IndirectRegister */ > + op->ol =3D 0; > + } > + else if (x =3D=3D 8 && !workaround) > + { > + op->reg =3D REGNO_CG1; > + op->am =3D 3; /* AMs_IndirectAutoIncrement */ > + op->ol =3D 0; > + } > +} >=20=20 > -static int > -msp430_srcoperand (struct msp430_operand_s * op, > - char * l, int bin, int * imm_op) > +static bfd_boolean > +msp430_srcoperand (struct msp430_operand_s *op, > + const char *operand_string, > + enum immediate_range_e imm_range) > { > - char *__tl =3D l; > + symbolS * symbol; > + char *opstr =3D ""; > + > + if (operand_string) > + { > + opstr =3D alloca (strlen (operand_string) + 1); > + strcpy (opstr, operand_string); > + } >=20=20 > /* Check if an immediate #VALUE. The hash sign should be only at the = beginning! */ > - if (*l =3D=3D '#') > + if (*opstr =3D=3D '#') > { > - char *h =3D l; > int vshift =3D -1; > - int rval =3D 0; > + int extractor_len =3D 0; >=20=20 > /* Check if there is: > - llo(x) - least significant 16 bits, x &=3D 0xffff > - lhi(x) - x =3D (x >> 16) & 0xffff, > - hlo(x) - x =3D (x >> 32) & 0xffff, > - hhi(x) - x =3D (x >> 48) & 0xffff > - The value _MUST_ be constant expression: #hlo(1231231231). */ > - > - *imm_op =3D 1; > + llo(x) - least significant 16 bits, x &=3D 0xffff > + lhi(x) - x =3D (x >> 16) & 0xffff, > + hlo(x) - x =3D (x >> 32) & 0xffff, > + hhi(x) - x =3D (x >> 48) & 0xffff > + The value _MUST_ be constant expression: #hlo(1231231231). */ >=20=20 > - if (strncasecmp (h, "#llo(", 5) =3D=3D 0) > + if (strncasecmp (opstr, "#llo(", 5) =3D=3D 0) > { > vshift =3D 0; > - rval =3D 3; > + extractor_len =3D 3; > } > - else if (strncasecmp (h, "#lhi(", 5) =3D=3D 0) > + else if (strncasecmp (opstr, "#lhi(", 5) =3D=3D 0) > { > vshift =3D 1; > - rval =3D 3; > + extractor_len =3D 3; > } > - else if (strncasecmp (h, "#hlo(", 5) =3D=3D 0) > + else if (strncasecmp (opstr, "#hlo(", 5) =3D=3D 0) > { > vshift =3D 2; > - rval =3D 3; > + extractor_len =3D 3; > } > - else if (strncasecmp (h, "#hhi(", 5) =3D=3D 0) > + else if (strncasecmp (opstr, "#hhi(", 5) =3D=3D 0) > { > vshift =3D 3; > - rval =3D 3; > + extractor_len =3D 3; > } > - else if (strncasecmp (h, "#lo(", 4) =3D=3D 0) > + else if (strncasecmp (opstr, "#lo(", 4) =3D=3D 0) > { > vshift =3D 0; > - rval =3D 2; > + extractor_len =3D 2; > } > - else if (strncasecmp (h, "#hi(", 4) =3D=3D 0) > + else if (strncasecmp (opstr, "#hi(", 4) =3D=3D 0) > { > vshift =3D 1; > - rval =3D 2; > + extractor_len =3D 2; > } >=20=20 > - op->reg =3D 0; /* Reg PC. */ > - op->am =3D 3; > + op->reg =3D REGNO_PC; > + op->am =3D AMs_Immediate; > op->ol =3D 1; /* Immediate will follow an instruction. */ > - __tl =3D h + 1 + rval; > - op->mode =3D OP_EXP; >=20=20 > - parse_exp (__tl, &(op->exp)); > + /* Extract the value after the hash and any extractor */ > + opstr =3D parse_exp (opstr + 1 + extractor_len, &(op->exp)); > + if (0 !=3D *opstr) > + { > + as_bad (_("garbage after immediate: %s"), operand_string); > + return FALSE; > + } > if (op->exp.X_op =3D=3D O_constant) > { > - int x =3D op->exp.X_add_number; > - > - if (vshift =3D=3D 0) > - { > - x =3D x & 0xffff; > - op->exp.X_add_number =3D x; > - } > - else if (vshift =3D=3D 1) > - { > - x =3D (x >> 16) & 0xffff; > - op->exp.X_add_number =3D x; > - } > - else if (vshift > 1) > - { > - if (x < 0) > - op->exp.X_add_number =3D -1; > - else > - op->exp.X_add_number =3D 0; /* Nothing left. */ > - x =3D op->exp.X_add_number; > - } > - > - if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768) > + if (0 <=3D vshift) > { > - as_bad (_("value %d out of range. Use #lo() or #hi()"), x); > - return 1; > - } > - > - /* Now check constants. */ > - /* Substitute register mode with a constant generator if applicable. = */ > + int is_negative =3D 0 > op->exp.X_add_number; > + unsigned int shift_bits =3D vshift * 16; >=20=20 > - x =3D (short) x; /* Extend sign. */ > - > - if (x =3D=3D 0) > - { > - op->reg =3D 3; > - op->am =3D 0; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D 1) > - { > - op->reg =3D 3; > - op->am =3D 1; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D 2) > - { > - op->reg =3D 3; > - op->am =3D 2; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D -1) > - { > - op->reg =3D 3; > - op->am =3D 3; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D 4) > - { > -#ifdef PUSH_1X_WORKAROUND > - if (bin =3D=3D 0x1200) > - { > - /* Remove warning as confusing. > - as_warn (_("Hardware push bug workaround")); */ > - } > - else > -#endif > - { > - op->reg =3D 2; > - op->am =3D 2; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - } > - else if (x =3D=3D 8) > - { > -#ifdef PUSH_1X_WORKAROUND > - if (bin =3D=3D 0x1200) > + if (shift_bits < (8 * sizeof (op->exp.X_add_number))) > { > - /* Remove warning as confusing. > - as_warn (_("Hardware push bug workaround")); */ > + offsetT shifted =3D op->exp.X_add_number >> shift_bits; > + shifted =3D MASK_16 (shifted); > + if (shifted =3D=3D MASK_16 (-1)) > + shifted =3D -1; > + op->exp.X_add_number =3D shifted; > } > else > -#endif > - { > - op->reg =3D 2; > - op->am =3D 3; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > + op->exp.X_add_number =3D is_negative ? -1 : 0; > } > + > + return valid_immediate (op->exp.X_add_number, imm_range); > } > - else if (op->exp.X_op =3D=3D O_symbol) > - { > - op->mode =3D OP_EXP; > - } > - else if (op->exp.X_op =3D=3D O_big) > + if (op->exp.X_op =3D=3D O_symbol || op->exp.X_op =3D=3D O_subtract) > + return TRUE; > + if (op->exp.X_op =3D=3D O_big) > { > - short x; > - if (vshift !=3D -1) > + if (0 <=3D vshift) > { > op->exp.X_op =3D O_constant; > - op->exp.X_add_number =3D 0xffff & generic_bignum[vshift]; > - x =3D op->exp.X_add_number; > - } > - else > - { > - as_bad (_ > - ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hh= i() "), > - l); > - return 1; > - } > - > - if (x =3D=3D 0) > - { > - op->reg =3D 3; > - op->am =3D 0; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D 1) > - { > - op->reg =3D 3; > - op->am =3D 1; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D 2) > - { > - op->reg =3D 3; > - op->am =3D 2; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D -1) > - { > - op->reg =3D 3; > - op->am =3D 3; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D 4) > - { > - op->reg =3D 2; > - op->am =3D 2; > - op->ol =3D 0; > - op->mode =3D OP_REG; > - } > - else if (x =3D=3D 8) > - { > - op->reg =3D 2; > - op->am =3D 3; > - op->ol =3D 0; > - op->mode =3D OP_REG; > + op->exp.X_add_number =3D MASK_16 (generic_bignum[vshift]); > + if (op->exp.X_add_number =3D=3D MASK_16 (-1)) > + op->exp.X_add_number =3D -1; > + return valid_immediate (op->exp.X_add_number, imm_range); > } > + as_bad (_("operand too big (use #llo(), etc.): %s"), > + operand_string); > + return FALSE; > } > - /* Redundant (yet) check. */ > - else if (op->exp.X_op =3D=3D O_register) > - as_bad > - (_("Registers cannot be used within immediate expression [%s]"), l); > - else > - as_bad (_("unknown operand %s"), l); > - > - return 0; > + as_bad (_("invalid immediate operand: %s"), operand_string); > + return FALSE; > } >=20=20 > /* Check if absolute &VALUE (assume that we can construct something li= ke ((a&b)<<7 + 25). */ > - if (*l =3D=3D '&') > + if (*opstr =3D=3D '&') > { > - char *h =3D l; > - > - op->reg =3D 2; /* reg 2 in absolute addr mode. */ > - op->am =3D 1; /* mode As =3D=3D 01 bin. */ > + op->reg =3D REGNO_CG1; /* reg 2 in absolute addr mode. */ > + op->am =3D AM_Absolute; /* mode As =3D=3D 01 bin. */ > op->ol =3D 1; /* Immediate value followed by instruction. */ > - __tl =3D h + 1; > - parse_exp (__tl, &(op->exp)); > - op->mode =3D OP_EXP; > - if (op->exp.X_op =3D=3D O_constant) > + opstr =3D parse_exp (opstr + 1, &(op->exp)); > + if (0 !=3D *opstr) > { > - int x =3D op->exp.X_add_number; > - > - if (x > 65535 || x < -32768) > - { > - as_bad (_("value out of range: %d"), x); > - return 1; > - } > + as_bad (_("garbage after absolute: %s"), operand_string); > + return FALSE; > } > - else if (op->exp.X_op =3D=3D O_symbol) > - ; > - else > - { > - /* Redundant (yet) check. */ > - if (op->exp.X_op =3D=3D O_register) > - as_bad > - (_("Registers cannot be used within absolute expression [%s]"), l= ); > - else > - as_bad (_("unknown expression in operand %s"), l); > - return 1; > - } > - return 0; > + if (op->exp.X_op =3D=3D O_constant) > + return valid_immediate (op->exp.X_add_number, imm_range); > + if (op->exp.X_op =3D=3D O_symbol || op->exp.X_op =3D=3D O_subtract) > + return TRUE; > + > + as_bad (_("invalid absolute operand: %s"), operand_string); > + return FALSE; > } >=20=20 > /* Check if indirect register mode @Rn / postincrement @Rn+. */ > - if (*l =3D=3D '@') > + if (*opstr =3D=3D '@') > { > - char *t =3D l; > - char *m =3D strchr (l, '+'); > - > - if (t !=3D l) > - { > - as_bad (_("unknown addressing mode %s"), l); > - return 1; > - } > - > - t++; > - if (*t !=3D 'r' && *t !=3D 'R') > + expressionS deref; > + char *plusp =3D strchr (opstr, '+'); > + > + if (NULL !=3D plusp) > + *plusp =3D 0; > + opstr =3D parse_exp (opstr + 1, &deref); > + if (NULL !=3D plusp) > + *plusp =3D '+'; > + if (deref.X_op !=3D O_register) > { > - as_bad (_("unknown addressing mode %s"), l); > - return 1; > + as_bad (_("invalid indirect operand: %s"), operand_string); > + return FALSE; > } >=20=20 > - t++; /* Points to the reg value. */ > - > - if (check_reg (t)) > + op->ol =3D 0; > + op->reg =3D deref.X_add_number; > + op->am =3D AMs_IndirectRegister; > + if ('+' =3D=3D *opstr) > { > - as_bad (_("Bad register name r%s"), t); > - return 1; > + op->am =3D AMs_IndirectAutoIncrement; > + ++opstr; > } > - > - op->mode =3D OP_REG; > - op->am =3D m ? 3 : 2; > - op->ol =3D 0; > - if (m) > - *m =3D 0; /* strip '+' */ > - op->reg =3D atoi (t); > - if (op->reg < 0 || op->reg > 15) > + if (0 !=3D *opstr) > { > - as_bad (_("MSP430 does not have %d registers"), op->reg); > - return 1; > + as_bad (_("garbage after indirection: %s"), operand_string); > + return FALSE; > } > - > - return 0; > + return TRUE; > } >=20=20 > /* Check if register indexed X(Rn). */ > do > { > - char *h =3D strrchr (l, '('); > - char *m =3D strrchr (l, ')'); > - char *t; > - > - *imm_op =3D 1; > + char *lparenp =3D strrchr (opstr, '('); > + char *rparenp; > + char *irendp; > + expressionS index_register; > + > + /* Commit to register if the operand ends with a parenthesized > + * register. */ > + if (NULL =3D=3D lparenp) > + break; > + rparenp =3D strchr (lparenp + 1, ')'); > + if (NULL =3D=3D rparenp) > + break; >=20=20 > - if (!h) > + *rparenp =3D 0; > + irendp =3D parse_exp (lparenp + 1, &index_register); > + *rparenp =3D ')'; > + if (index_register.X_op !=3D O_register || irendp !=3D rparenp) > break; > - if (!m) > - { > - as_bad (_("')' required")); > - return 1; > - } >=20=20 > - t =3D h; > - op->am =3D 1; > + op->am =3D AM_Indexed; > op->ol =3D 1; > - /* Extract a register. */ > - t++; /* Advance pointer. */ > + op->reg =3D index_register.X_add_number; >=20=20 > - if (*t !=3D 'r' && *t !=3D 'R') > + /* Extract what precedes (Rn) which should be an expression */ > + *lparenp =3D 0; > + opstr =3D parse_exp (opstr, &op->exp); > + *lparenp =3D '('; > + if (opstr !=3D lparenp) > { > - as_bad (_ > - ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"= ), > - l); > - return 1; > + as_bad (_("garbage after offset in indexed operand: %s"), > + operand_string); > + return FALSE; > } > - t++; >=20=20 > - op->reg =3D *t - '0'; > - if (op->reg > 9 || op->reg < 0) > - { > - as_bad (_("unknown operator (r%s substituted as a register name"), > - t); > - return 1; > - } > - t++; > - if (*t !=3D ')') > - { > - op->reg =3D op->reg * 10; > - op->reg +=3D *t - '0'; > - > - if (op->reg > 15) > - { > - as_bad (_("unknown operator %s"), l); > - return 1; > - } > - if (op->reg =3D=3D 2) > - { > - as_bad (_("r2 should not be used in indexed addressing mode")); > - return 1; > - } > - > - if (*(t + 1) !=3D ')') > - { > - as_bad (_("unknown operator %s"), l); > - return 1; > - } > - } > - > - /* Extract constant. */ > - __tl =3D l; > - *h =3D 0; > - op->mode =3D OP_EXP; > - parse_exp (__tl, &(op->exp)); > + /* Validate constant, convert to indirect if possible */ > if (op->exp.X_op =3D=3D O_constant) > { > - int x =3D op->exp.X_add_number; > - > - if (x > 65535 || x < -32768) > - { > - as_bad (_("value out of range: %d"), x); > - return 1; > - } > + if (!valid_immediate (op->exp.X_add_number, imm_range)) > + return FALSE; >=20=20 > - if (x =3D=3D 0) > + if (op->exp.X_add_number =3D=3D 0) > { > - op->mode =3D OP_REG; > - op->am =3D 2; > + op->am =3D AMs_IndirectRegister; > op->ol =3D 0; > - return 0; > } > + return TRUE; > } > - else if (op->exp.X_op =3D=3D O_symbol) > - ; > - else > - { > - /* Redundant (yet) check. */ > - if (op->exp.X_op =3D=3D O_register) > - as_bad > - (_("Registers cannot be used as a prefix of indexed expression [%= s]"), l); > - else > - as_bad (_("unknown expression in operand %s"), l); > - return 1; > - } > + if (op->exp.X_op =3D=3D O_symbol || op->exp.X_op =3D=3D O_subtract) > + return TRUE; >=20=20 > - return 0; > + as_bad (_("invalid indexed operand: %s"), operand_string); > + return FALSE; > } > while (0); >=20=20 > - /* Register mode 'mov r1,r2'. */ > - do > + /* Assume a symbolic, but correct if it's a register */ > + opstr =3D parse_exp (opstr, &(op->exp)); > + if (op->exp.X_op =3D=3D O_register) > { > - char *t =3D l; > + int regno =3D op->exp.X_add_number; >=20=20 > - /* Operand should be a register. */ > - if (*t =3D=3D 'r' || *t =3D=3D 'R') > + if (0 !=3D *opstr) > { > - int x =3D atoi (t + 1); > - > - if (check_reg (t + 1)) > - break; > - > - if (x < 0 || x > 15) > - break; /* Symbolic mode. */ > - > - op->mode =3D OP_REG; > - op->am =3D 0; > - op->ol =3D 0; > - op->reg =3D x; > - return 0; > + as_bad (_("garbage after register operand: %s"), operand_string); > + return FALSE; > } > + memset (op, 0, sizeof (*op)); > + op->reg =3D regno; > + op->am =3D AM_Register; > + op->ol =3D 0; > + return TRUE; > } > - while (0); > + if (0 !=3D *opstr) > + { > + as_bad (_("garbage after operand: %s"), operand_string); > + return FALSE; > + } > + op->reg =3D REGNO_PC; > + op->am =3D AM_Symbolic; > + op->ol =3D 1; > + /* Make the offset PC-relative */ > + symbol =3D make_expr_symbol (&op->exp); > + memset (&op->exp, 0, sizeof (op->exp)); > + op->exp.X_op =3D O_subtract; > + op->exp.X_add_symbol =3D symbol; > + op->exp.X_op_symbol =3D expr_build_dot (); > + > + return TRUE; > +} >=20=20 > - /* Symbolic mode 'mov a, b' =3D=3D 'mov x(pc), y(pc)'. */ > - do > +static bfd_boolean > +convert_operand_to_dst (struct msp430_operand_s *dop, > + const struct msp430_operand_s *sop, > + const char *operand_string) > +{ > + if (sop !=3D dop) > + *dop =3D *sop; > + > + if (dop->am <=3D AM_Indexed) > + return TRUE; > + > + /* Destination does not recognize indirect register: convert to > + * indexed register with zero offset */ > + if (dop->am =3D=3D AMs_IndirectRegister) > { > - op->mode =3D OP_EXP; > - op->reg =3D 0; /* PC relative... be careful. */ > - op->am =3D 1; > - op->ol =3D 1; > - __tl =3D l; > - parse_exp (__tl, &(op->exp)); > - return 0; > + dop->am =3D AM_Indexed; > + dop->ol =3D 1; > + memset (&dop->exp, 0, sizeof (dop->exp)); > + dop->exp.X_op =3D O_constant; > + dop->exp.X_add_number =3D 0; > + return TRUE; > } > - while (0); >=20=20 > - /* Unreachable. */ > - as_bad (_("unknown addressing mode for operand %s"), l); > - return 1; > + /* Note that symbols and absolute addresses are indexed registers */ > + as_bad (_("invalid destination (must be register or indexed register):= %s"), > + operand_string); > + return FALSE; > } >=20=20 >=20=20 > -static int > -msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin) > +static bfd_boolean > +msp430_dstoperand (struct msp430_operand_s *op, > + const char *operand_string, > + enum immediate_range_e imm_range) > { > - int dummy; > - int ret =3D msp430_srcoperand (op, l, bin, & dummy); > + if (!msp430_srcoperand (op, operand_string, imm_range)) > + return FALSE; > + return convert_operand_to_dst (op, op, operand_string); > +} >=20=20 > - if (ret) > - return ret; > +static void > +msp430_repeat_insn (int dummy ATTRIBUTE_UNUSED) > +{ > + char *operand =3D 0; > + struct msp430_operand_s op; > + char *line =3D input_line_pointer; >=20=20 > - if (op->am =3D=3D 2) > + if (msp430_cpu < MSP430_CPU_MSP430X) > { > - char *__tl =3D "0"; > + as_bad (_("Repeatable instructions require 430X-based mcu")); > + return; > + } >=20=20 > - op->mode =3D OP_EXP; > - op->am =3D 1; > - op->ol =3D 1; > - parse_exp (__tl, &(op->exp)); > + if (msp430x_repeats) > + as_warn (_("two consecutive .rpt pseudo-ops. Previous .rpt discarded= ")); > + msp430x_repeats =3D 0; >=20=20 > - if (op->exp.X_op !=3D O_constant || op->exp.X_add_number !=3D 0) > - { > - as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"), > - op->reg, op->reg); > - return 1; > - } > - return 0; > + if (!*line || *line =3D=3D '\n') > + { > + as_bad (_("rpt pseudo-op requires 1 operand")); > + return; > } >=20=20 > - if (op->am > 1) > + memset (&op, 0, sizeof (op)); > + operand =3D get_operand (); > + > + if (msp430_srcoperand (&op, operand, IMM_RANGE_REPETITION_COUNT)) > { > - as_bad (_ > - ("this addressing mode is not applicable for destination operand"= )); > - return 1; > + if (op.am !=3D AM_Register /* Rn */ > + && op.am !=3D AMs_Immediate) /* #N */ > + as_bad (_("rpt pseudo-op requires immediate or register operand")); > + else if (op.am =3D=3D AM_Register) /* rpt Rn */ > + msp430x_repeats =3D 0x80 | op.reg; > + else > + msp430x_repeats =3D op.exp.X_add_number - 1; > } > - return 0; > + > + xfree (operand); > } >=20=20 > +enum msp430_fixup_e { > + FX_INVALID, > + > + /* R_MSP430_16, odd check SRC */ > + FX_16S, > + > + /* R_MSP430_16, odd checks DST */ > + FX_16D, > + > + /* R_MSP430X_SRC, odd check SRC */ > + FX_X20S, > + > + /* R_MSP430X_DST, odd check DST */ > + FX_X20D, > + > + /* R_MSP430X_DST, odd check SRC (for pushx) */ > + FX_X20D_SRCI, > + > + /* R_MSP430X_DST_2ND, odd check DST */ > + FX_X20D2, > + > + /* R_MSP430X_S */ > + FX_A20S, > +=20=20 > + /* R_MSP430X_S, disallows byte variant (for bra) */ > + FX_A20S_W, > +=20=20 > + /* R_MSP430X_D */ > + FX_A20D, > + > + /* R_MSP430X_INDXD */ > + FX_A16 > +}; > + > +static void > +record_fixup (int where, > + int size, > + opwidth_t op_width, > + struct msp430_operand_s *op, > + enum msp430_fixup_e fixup) > +{ > + int is_pcrel; > + bfd_reloc_code_real_type reloc =3D BFD_RELOC_NONE; > + > + is_pcrel =3D (op->reg =3D=3D REGNO_PC && op->am =3D=3D AM_Indexed && o= p->exp.X_op =3D=3D O_subtract); > + switch (fixup) > + { > + case FX_16D: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430_16_PCREL : BFD_RELOC_MSP430_= 16; > + if (op_width =3D=3D BYTE_OP || OP_DST_IMMEDIATE_PERMITS_ODD (*op)) > + reloc =3D is_pcrel ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_= 16_BYTE; > + break; > + case FX_16S: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430_16_PCREL : BFD_RELOC_MSP430_= 16; > + if (op_width =3D=3D BYTE_OP || OP_SRC_IMMEDIATE_PERMITS_ODD (*op)) > + reloc =3D is_pcrel ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_= 16_BYTE; > + break; > + case FX_X20S: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_SRC : BFD_RELOC_MSP43= 0X_SRC; > + if (op_width =3D=3D BYTE_OP || OP_SRC_IMMEDIATE_PERMITS_ODD (*op)) > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_SRC_BYTE : BFD_RELOC_MSP43= 0X_SRC_BYTE; > + break; > + case FX_X20D: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_DST : BFD_RELOC_MSP43= 0X_DST; > + if (op_width =3D=3D BYTE_OP || OP_DST_IMMEDIATE_PERMITS_ODD (*op)) > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_DST_BYTE : BFD_RELOC_MSP43= 0X_DST_BYTE; > + break; > + case FX_X20D_SRCI: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_DST : BFD_RELOC_MSP43= 0X_DST; > + if (op_width =3D=3D BYTE_OP || OP_SRC_IMMEDIATE_PERMITS_ODD (*op)) > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_DST_BYTE : BFD_RELOC_MSP43= 0X_DST_BYTE; > + break; > + case FX_X20D2: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_DST_2ND : BFD_RELOC_M= SP430X_DST_2ND; > + if (op_width =3D=3D BYTE_OP || OP_DST_IMMEDIATE_PERMITS_ODD (*op)) > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE : BFD_RELOC_M= SP430X_DST_2ND_BYTE; > + break; > + case FX_A20S_W: > + case FX_A20S: > + /* NB: No A20S that are PCREL */ > + reloc =3D /* is_pcrel ? BFD_RELOC_MSP430X_PCREL_S : */ BFD_RELOC_M= SP430X_S; > + if (FX_A20S_W !=3D fixup && (op_width =3D=3D BYTE_OP || OP_SRC_IMM= EDIATE_PERMITS_ODD (*op))) > + reloc =3D /* is_pcrel ? BFD_RELOC_MSP430X_PCREL_S_BYTE : */ BFD_RELOC_M= SP430X_S_BYTE; > + break; > + case FX_A20D: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_D : BFD_RELOC_MSP430X= _D; > + break; > + case FX_A16: > + reloc =3D is_pcrel ? BFD_RELOC_MSP430X_PCREL_INDXD : BFD_RELOC_MSP= 430X_INDXD; > + break; > + default: > + gas_assert (0); > + } > + fix_new_exp (frag_now, where, size, &op->exp, is_pcrel, reloc); > +} >=20=20 > /* Parse instruction operands. > Return binary opcode. */ >=20=20 > static unsigned int > -msp430_operands (struct msp430_opcode_s * opcode, char * line) > +msp430_operands (struct msp430_opcode_s const *opcode, char *line) > { > int bin =3D opcode->bin_opcode; /* Opcode mask. */ > - int __is =3D 0; > - char l1[MAX_OP_LEN], l2[MAX_OP_LEN]; > - char *frag; > - int where; > + enum msp430_fixup_e fixup; > + int insn_len_words =3D 0; > + char *l1 =3D 0; > + char *l2 =3D 0; > + char *frag =3D 0; > + int where =3D 0; > struct msp430_operand_s op1, op2; > - int res =3D 0; > + bfd_boolean bad_operand =3D FALSE; > static short ZEROS =3D 0; > - int byte_op, imm_op; > + opwidth_t op_width; >=20=20 > /* Opcode is the one from opcodes table > line contains something like > [.w] @r2+, 5(R1) > or > - .b @r2+, 5(R1). */ > + .b @r2+, 5(R1) > + or > + .a @r2+, 5(R1) */ > + > + /* Extract operation width */ > + op_width =3D DEFAULT_OP; > + if (*line =3D=3D '.') > + { > + int opchar; > + opchar =3D TOLOWER (line[1]); > + if (opchar =3D=3D 'b') > + op_width =3D BYTE_OP; > + else if (opchar =3D=3D 'w') > + op_width =3D WORD_OP; > + else if (opchar =3D=3D 'a') > + op_width =3D ADDR_OP; > + if (op_width =3D=3D DEFAULT_OP || !ISSPACE (line[2])) > + { > + as_bad (_("unrecognized opcode width: %s%s"), opcode->name, line); > + return 0; > + } > + line +=3D 2; > + } >=20=20 > - /* Check if byte or word operation. */ > - if (*line =3D=3D '.' && TOLOWER (*(line + 1)) =3D=3D 'b') > + /* Verify specified width is supported by operation */ > + if ((op_width =3D=3D WORD_OP && !(opcode_modifier (opcode) & MOD_W)) > + || (op_width =3D=3D BYTE_OP && !(opcode_modifier (opcode) & MOD_B)) > + || (op_width =3D=3D ADDR_OP && !(opcode_modifier (opcode) & MOD_A)= )) > { > - bin |=3D BYTE_OPERATION; > - byte_op =3D 1; > + static char *const modifier[] =3D { "", ".w", ".b", ".a" }; > + as_bad (_("%s%s is not a supported operation/width combination"), > + opcode->name, modifier[op_width]); > + return 0; > + } > + if (DEFAULT_OP =3D=3D op_width) > + op_width =3D WORD_OP; > + > + if (opcode_format (opcode) =3D=3D FMT_X_DOUBLE_OPERAND > + || opcode_format (opcode) =3D=3D FMT_X_SINGLE_OPERAND > + || opcode_format (opcode) =3D=3D FMT_X_EMULATED) > + { > + switch (op_width) > + { > + case DEFAULT_OP: > + case WORD_OP: > + bin |=3D NON_ADDR_OPERATION; > + break; > + case BYTE_OP: > + bin |=3D NON_ADDR_OPERATION; > + bin |=3D BYTE_OPERATION_X; > + break; > + case ADDR_OP: > + bin |=3D BYTE_OPERATION_X; > + break; > + } > } > else > - byte_op =3D 0; > + { > + if (msp430x_repeats) > + { > + as_bad (_("%s instruction is not repeatable"), opcode->name); > + msp430x_repeats =3D 0; > + return 0; > + } >=20=20 > - /* skip .[bwBW]. */ > - while (! ISSPACE (*line) && *line) > - line++; > + if (opcode_format (opcode) < FMT_X && op_width =3D=3D BYTE_OP) /* = 430 instructions */ > + bin |=3D BYTE_OPERATION; > + } >=20=20 > if (opcode->insn_opnumb && (!*line || *line =3D=3D '\n')) > { > @@ -1416,424 +1836,789 @@ msp430_operands (struct msp430_opcode_s * opcod= e, char * line) > return 0; > } >=20=20 > - memset (l1, 0, sizeof (l1)); > - memset (l2, 0, sizeof (l2)); > + input_line_pointer =3D line; > + > memset (&op1, 0, sizeof (op1)); > memset (&op2, 0, sizeof (op2)); >=20=20 > - imm_op =3D 0; > - > - switch (opcode->fmt) > + switch (opcode_format (opcode)) > { > - case 0: /* Emulated. */ > - switch (opcode->insn_opnumb) > + case FMT_EMULATED: /* Emulated. */ > + switch (opcode_variant (opcode)) > { > - case 0: > - /* Set/clear bits instructions. */ > - __is =3D 2; > - frag =3D frag_more (__is); > + case V_NOOP: /* Exemplar: setz */ > + /* Set/clear SR bits instructions, ret, nop */ > + insn_len_words =3D 1; > + frag =3D frag_more (2 * insn_len_words); > bfd_putl16 ((bfd_vma) bin, frag); > - dwarf2_emit_insn (__is); > break; > - case 1: > + case V_NONE: /* Exemplar: inv */ > /* Something which works with destination operand. */ > - line =3D extract_operand (line, l1, sizeof (l1)); > - res =3D msp430_dstoperand (&op1, l1, opcode->bin_opcode); > - if (res) > + l1 =3D get_operand (); > + if (!msp430_dstoperand (&op1, l1, IMM_RANGE_INT16)) > break; >=20=20 > bin |=3D (op1.reg | (op1.am << 7)); > - __is =3D 1 + op1.ol; > - frag =3D frag_more (2 * __is); > + insn_len_words =3D 1 + op1.ol; > + frag =3D frag_more (2 * insn_len_words); > where =3D frag - frag_now->fr_literal; > bfd_putl16 ((bfd_vma) bin, frag); > - dwarf2_emit_insn (2 * __is); >=20=20 > - if (op1.mode =3D=3D OP_EXP) > + if (OP_HAS_IMMEDIATE (op1)) > { > where +=3D 2; > bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > - > - if (op1.reg) > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), FALSE, CHECK_RELOC_MSP430); > - else > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); > + record_fixup (where, 2, op_width, &op1, FX_16D); > } > break; >=20=20 > - case 2: > + case V_SHIFT: /* Exemplar: rlc */ > { > - /* Shift instruction. */ > - line =3D extract_operand (line, l1, sizeof (l1)); > - strncpy (l2, l1, sizeof (l2)); > - l2[sizeof (l2) - 1] =3D '\0'; > - res =3D msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); > - res +=3D msp430_dstoperand (&op2, l2, opcode->bin_opcode); > - > - if (res) > - break; /* An error occurred. All warnings were done before. */ > + /* Shift instruction simulated by add op1, op2 */ > + l1 =3D get_operand (); > + if (!msp430_srcoperand (&op1, l1, IMM_RANGE_INT16)) > + break; > + if (!convert_operand_to_dst (&op2, &op1, l1)) > + break; >=20=20 > bin |=3D (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)); >=20=20 > - __is =3D 1 + op1.ol + op2.ol; /* insn size in words. */ > - frag =3D frag_more (2 * __is); > + insn_len_words =3D 1 + op1.ol + op2.ol; /* insn size in words. */ > + frag =3D frag_more (2 * insn_len_words); > where =3D frag - frag_now->fr_literal; > bfd_putl16 ((bfd_vma) bin, frag); > - dwarf2_emit_insn (2 * __is); > -=09=20=20=20=20 > - if (op1.mode =3D=3D OP_EXP) > + > + if (OP_HAS_IMMEDIATE (op1)) > { > where +=3D 2; /* Advance 'where' as we do not know _where_. */ > bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > - > - if (op1.reg || (op1.reg =3D=3D 0 && op1.am =3D=3D 3)) /* Not PC relati= ve. */ > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), FALSE, CHECK_RELOC_MSP430); > - else > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); > + record_fixup (where, 2, op_width, &op1, FX_16S); > } >=20=20 > - if (op2.mode =3D=3D OP_EXP) > + if (OP_HAS_IMMEDIATE (op2)) > { > - imm_op =3D 0; > - bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is =3D=3D 3) ? 2 : 0)); > - > - if (op2.reg) /* Not PC relative. */ > - fix_new_exp (frag_now, where + 2, 2, > - &(op2.exp), FALSE, CHECK_RELOC_MSP430); > - else > - fix_new_exp (frag_now, where + 2, 2, > - &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL); > + bfd_putl16 ((bfd_vma) ZEROS, > + frag + 2 + ((insn_len_words =3D=3D 3) ? 2 : 0)); > + record_fixup (where + 2, 2, op_width, &op2, FX_16D); > } > break; > } > - case 3: > + case V_BR: /* Exemplar: br */ > /* Branch instruction =3D> mov dst, r0. */ > - line =3D extract_operand (line, l1, sizeof (l1)); > - > - res =3D msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); > - if (res) > + l1 =3D get_operand (); > + if (!msp430_srcoperand (&op1, l1, IMM_RANGE_INT16)) > break; > - > - byte_op =3D 0; > - imm_op =3D 0; > + msp430_substitute_CG (&op1, WORD_OP, 0); >=20=20 > bin |=3D ((op1.reg << 8) | (op1.am << 4)); > - __is =3D 1 + op1.ol; > - frag =3D frag_more (2 * __is); > + insn_len_words =3D 1 + op1.ol; > + frag =3D frag_more (2 * insn_len_words); > where =3D frag - frag_now->fr_literal; > bfd_putl16 ((bfd_vma) bin, frag); > - dwarf2_emit_insn (2 * __is); >=20=20 > - if (op1.mode =3D=3D OP_EXP) > + if (OP_HAS_IMMEDIATE (op1)) > { > where +=3D 2; > bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > - > - if (op1.reg || (op1.reg =3D=3D 0 && op1.am =3D=3D 3)) > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), FALSE, CHECK_RELOC_MSP430); > - else > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); > + /* NB: Use DST_IMMEDIATE since this is going into r0 */ > + record_fixup (where, 2, op_width, &op1, FX_16D); > } > break; > } > break; >=20=20 > - case 1: /* Format 1, double operand. */ > - line =3D extract_operand (line, l1, sizeof (l1)); > - line =3D extract_operand (line, l2, sizeof (l2)); > - res =3D msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); > - res +=3D msp430_dstoperand (&op2, l2, opcode->bin_opcode); > + case FMT_DOUBLE_OPERAND: /* Exemplar: and */ > + /* Format 1, double operand. */ > + l1 =3D get_operand (); > + l2 =3D get_operand (); > + bad_operand =3D !msp430_srcoperand (&op1, l1, IMM_RANGE_INT16); > + bad_operand |=3D !msp430_dstoperand (&op2, l2, IMM_RANGE_INT16); > + if (bad_operand) > + break; >=20=20 > - if (res) > - break; /* Error occurred. All warnings were done before. */ > + msp430_substitute_CG (&op1, op_width, 0); >=20=20 > bin |=3D (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)= ); >=20=20 > - __is =3D 1 + op1.ol + op2.ol; /* insn size in words. */ > - frag =3D frag_more (2 * __is); > + insn_len_words =3D 1 + op1.ol + op2.ol; /* insn size in words. */ > + frag =3D frag_more (2 * insn_len_words); > where =3D frag - frag_now->fr_literal; > bfd_putl16 ((bfd_vma) bin, frag); > - dwarf2_emit_insn (2 * __is); >=20=20 > - if (op1.mode =3D=3D OP_EXP) > + if (OP_HAS_IMMEDIATE (op1)) > { > where +=3D 2; /* Advance where as we do not know _where_. */ > bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > - > - if (op1.reg || (op1.reg =3D=3D 0 && op1.am =3D=3D 3)) /* Not PC relat= ive. */ > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), FALSE, CHECK_RELOC_MSP430); > - else > - fix_new_exp (frag_now, where, 2, > - &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); > + record_fixup (where, 2, op_width, &op1, FX_16S); > } >=20=20 > - if (op2.mode =3D=3D OP_EXP) > + if (OP_HAS_IMMEDIATE (op2)) > { > - imm_op =3D 0; > - bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is =3D=3D 3) ? 2 : 0)); > - > - if (op2.reg) /* Not PC relative. */ > - fix_new_exp (frag_now, where + 2, 2, > - &(op2.exp), FALSE, CHECK_RELOC_MSP430); > - else > - fix_new_exp (frag_now, where + 2, 2, > - &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL); > + bfd_putl16 ((bfd_vma) ZEROS, > + frag + 2 + ((insn_len_words =3D=3D 3) ? 2 : 0)); > + record_fixup (where + 2, 2, op_width, &op2, FX_16D); > } > break; >=20=20 > - case 2: /* Single-operand mostly instr. */ > - if (opcode->insn_opnumb =3D=3D 0) > + case FMT_SINGLE_OPERAND: /* Exemplar: sxt, call, reti */ > + /* Single-operand mostly instr. */ > + if (opcode_variant (opcode) =3D=3D V_RETI) /* Exemplar: reti */ > { > /* reti instruction. */ > - frag =3D frag_more (2); > + insn_len_words =3D 1; > + frag =3D frag_more (2 * insn_len_words); > bfd_putl16 ((bfd_vma) bin, frag); > - dwarf2_emit_insn (2); > break; > } >=20=20 > - line =3D extract_operand (line, l1, sizeof (l1)); > - res =3D msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op); > - if (res) > - break; /* Error in operand. */ > + l1 =3D get_operand (); > + if (!msp430_srcoperand (&op1, l1, IMM_RANGE_INT16)) > + break; /* Error in operand. */ > + msp430_substitute_CG (&op1, op_width, erratum_applies (ERRATUM_CPU= 4) > + && (opcode->bin_opcode =3D=3D 0x1200)); >=20=20 > bin |=3D op1.reg | (op1.am << 4); > - __is =3D 1 + op1.ol; > - frag =3D frag_more (2 * __is); > + insn_len_words =3D 1 + op1.ol; > + frag =3D frag_more (2 * insn_len_words); > where =3D frag - frag_now->fr_literal; > bfd_putl16 ((bfd_vma) bin, frag); > - dwarf2_emit_insn (2 * __is); >=20=20 > - if (op1.mode =3D=3D OP_EXP) > + if (OP_HAS_IMMEDIATE (op1)) > { > bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > - > - if (op1.reg || (op1.reg =3D=3D 0 && op1.am =3D=3D 3)) /* Not PC relat= ive. */ > - fix_new_exp (frag_now, where + 2, 2, > - &(op1.exp), FALSE, CHECK_RELOC_MSP430); > - else > - fix_new_exp (frag_now, where + 2, 2, > - &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL); > + record_fixup (where + 2, 2, op_width, &op1, > + opcode_variant (opcode) =3D=3D V_PUSH ? FX_16S : FX_16D); > } > break; >=20=20 > - case 3: /* Conditional jumps instructions. */ > - line =3D extract_operand (line, l1, sizeof (l1)); > - /* l1 is a label. */ > - if (l1[0]) > + case FMT_JUMP: /* Exemplar: jmp */ > + { > + expressionS exp; > +=09 > + /* Conditional jumps instructions. */ > + l1 =3D get_operand (); > + parse_exp(l1, &exp); > + if (exp.X_op =3D=3D O_absent) > + break; > +=20=20=20=20=20=20 > + insn_len_words =3D 1; > + frag =3D frag_more (2 * insn_len_words); /* Instr size is 1 word. */ > + > + if (exp.X_op =3D=3D O_constant) > + { > + int x =3D exp.X_add_number; > + > + if (MSP430_ODD (x)) > + { > + as_bad (_("jump offset must be even: %s"), l1); > + break; > + } > + bin |=3D MASK_10 (exp.X_add_number / 2); > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else if (exp.X_op =3D=3D O_symbol || exp.X_op =3D=3D O_subtract) > + { > + where =3D frag - frag_now->fr_literal; > + bfd_putl16 ((bfd_vma) bin, frag); > + fix_new_exp (frag_now, where, 2, &exp, TRUE, BFD_RELOC_MSP430_10_PC= REL); > + } > + else > + as_bad (_("unrecognized jump target: %s"), l1); > + } > + break; > + > + case FMT_X_DOUBLE_OPERAND: /* Exemplar: movx */ > + /* Extended Format 1 ( double operand). */ > + l1 =3D get_operand (); > + l2 =3D get_operand (); > + bad_operand =3D !msp430_srcoperand (&op1, l1, IMM_RANGE_INT20); > + bad_operand |=3D !msp430_dstoperand (&op2, l2, IMM_RANGE_INT20); > + if (bad_operand) > + break; /* Error occurred. All warnings were done before. */ > + > + msp430_substitute_CG (&op1, op_width, 0); > + > + if (msp430x_repeats > + && (OP_HAS_IMMEDIATE (op1) || OP_HAS_IMMEDIATE (op2))) > { > - char *m =3D l1; > - expressionS exp; > + as_bad (_("Repeated instruction must have register mode operands")); > + msp430x_repeats =3D 0; > + break; > + } > + bin |=3D msp430x_repeats; > + msp430x_repeats =3D 0; >=20=20 > - if (*m =3D=3D '$') > - m++; > + bin |=3D (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)= ) << 16; >=20=20 > - parse_exp (m, &exp); > - frag =3D frag_more (2); /* Instr size is 1 word. */ > + insn_len_words =3D 2 + op1.ol + op2.ol; /* insn size in words, opc= ode is 2 words wide. */ > + frag =3D frag_more (2 * insn_len_words); > + where =3D frag - frag_now->fr_literal; > + bfd_putl32 ((bfd_vma) bin, frag); >=20=20 > - /* In order to handle something like: > + if (OP_HAS_IMMEDIATE (op1)) > + { > + bfd_putl16 ((bfd_vma) ZEROS, frag + 4); > + record_fixup (where, 2, op_width, &op1, FX_X20S); > + } >=20=20 > - and #0x8000, r5 > - tst r5 > - jz 4 ; skip next 4 bytes > - inv r5 > - inc r5 > - nop ; will jump here if r5 positive or zero > + if (OP_HAS_IMMEDIATE (op2)) > + { > + bfd_putl16 ((bfd_vma) ZEROS, > + frag + 4 + ((insn_len_words =3D=3D 4) ? 2 : 0)); > + record_fixup (where, 2, op_width, &op2, OP_HAS_IMMEDIATE (op1) ? FX_X= 20D2 : FX_X20D); > + } > + break; >=20=20 > - jCOND -n ;assumes jump n bytes backward: > + case FMT_X_SINGLE_OPERAND: /* Exemplar: swpbx, rrcx, pushx */ > + /* Extended format 2 (single-operand). */ > + l1 =3D get_operand (); > + if (!msp430_srcoperand (&op1, l1, IMM_RANGE_INT20)) > + break; /* Error in operand. */ >=20=20 > - mov r5,r6 > - jmp -2 > + msp430_substitute_CG (&op1, op_width, 0); > + if (opcode_variant (opcode) !=3D V_PUSHX && OP_HAS_IMMEDIATE (op1)= && op1.am =3D=3D AMs_Immediate) /* #N */ > + { > + as_bad (_("bad operand [%s]"), l1); > + break; > + } >=20=20 > - is equal to: > - lab: > - mov r5,r6 > - jmp lab > + if (msp430x_repeats && OP_HAS_IMMEDIATE (op1)) > + { > + as_bad (_("Repeated instruction must have register mode operand")); > + msp430x_repeats =3D 0; > + break; > + } > + bin |=3D msp430x_repeats; > + msp430x_repeats =3D 0; >=20=20 > - jCOND $n ; jump from PC in either direction. */ > + /* sxtx.a | swpbx.a opcode */ > + if (opcode_variant (opcode) =3D=3D V_SWPSXT && op_width =3D=3D ADD= R_OP) > + bin ^=3D BYTE_OPERATION_X; >=20=20 > - if (exp.X_op =3D=3D O_constant) > - { > - int x =3D exp.X_add_number; > + bin |=3D (op1.reg | (op1.am << 4)) << 16; > + insn_len_words =3D 2 + op1.ol; /* insn size in words, opcode is 2 = words wide. */ > + frag =3D frag_more (2 * insn_len_words); > + where =3D frag - frag_now->fr_literal; > + bfd_putl32 ((bfd_vma) bin, frag); >=20=20 > - if (x & 1) > - { > - as_warn (_("Even number required. Rounded to %d"), x + 1); > - x++; > - } > + if (OP_HAS_IMMEDIATE (op1)) > + { > + bfd_putl16 ((bfd_vma) ZEROS, frag + 4); > + record_fixup (where, 2, op_width, &op1, > + opcode_variant (opcode) =3D=3D V_PUSHX ? FX_X20D_SRCI : FX_X20D); > + } > + break; >=20=20 > - if ((*l1 =3D=3D '$' && x > 0) || x < 0) > - x -=3D 2; > + case FMT_X_EXCEPTION: /* Exemplar: calla, popm, pushm, rrcm */ > + /* calla, pushm, popm, rrcm, rrum, rram, rlam */ > + bin =3D opcode->bin_opcode; /* remove WB/AL bits */ > + l1 =3D get_operand (); > + switch (opcode_variant (opcode)) > + { > + case V_CALLA: /* Exemplar: calla */ > + if (!msp430_srcoperand (&op1, l1, IMM_RANGE_INT20)) > + break; /* Error in operand. */ >=20=20 > - x >>=3D 1; > + insn_len_words =3D 1 + op1.ol; > + frag =3D frag_more (insn_len_words * 2); >=20=20 > - if (x > 512 || x < -511) > + if (!OP_HAS_IMMEDIATE (op1) && op1.am !=3D AM_Indexed) > + { > + bin |=3D op1.reg | 0x0040 | (op1.am << 4); > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else > + { > + fixup =3D FX_A20D; > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + where =3D frag - frag_now->fr_literal; > + if (op1.am =3D=3D AM_Indexed) > { > - as_bad (_("Wrong displacement %d"), x << 1); > - break; > + if (op1.reg =3D=3D REGNO_PC || op1.reg =3D=3D REGNO_CG1) > + { > + bin |=3D 0x0080; > + if (op1.reg =3D=3D REGNO_PC) > + bin |=3D 0x0010; > + } > + else > + { > + bin |=3D 0x0050 | op1.reg; > + fixup =3D FX_A16; > + } > + } > + else > + { > + gas_assert (op1.am =3D=3D AMs_Immediate); > + bin |=3D 0x00b0; > } > - > - bin |=3D x & 0x3ff; > bfd_putl16 ((bfd_vma) bin, frag); > + record_fixup (where, 2, op_width, &op1, fixup); > } > - else if (exp.X_op =3D=3D O_symbol && *l1 !=3D '$') > + break; > + case V_ROTM: /* Exemplar: rrcm */ > + l2 =3D get_operand (); > + bad_operand =3D !msp430_srcoperand (&op1, l1, IMM_RANGE_ROTATE_COUNT); > + bad_operand |=3D !msp430_dstoperand (&op2, l2, IMM_RANGE_INT20); > + if (bad_operand) > + break; /* An error occurred. All warnings were done before. */ > + > + if (op_width !=3D ADDR_OP) > + bin |=3D (1 << 4); > + > + if (!OP_HAS_IMMEDIATE (op1) || op1.am !=3D AMs_Immediate) /* not #imm= */ > { > - where =3D frag - frag_now->fr_literal; > - fix_new_exp (frag_now, where, 2, > - &exp, TRUE, BFD_RELOC_MSP430_10_PCREL); > + as_bad (_("bad operand [%s]"), l1); > + break; > + } >=20=20 > - bfd_putl16 ((bfd_vma) bin, frag); > + bin |=3D ((op1.exp.X_add_number - 1) & 0x0003) << 10; > + > + if (OP_HAS_IMMEDIATE (op2)) > + { > + as_bad (_("bad operand [%s]"), l2); > + break; > } > - else if (*l1 =3D=3D '$') > + bin |=3D op2.reg; > + > + insn_len_words =3D 1; > + frag =3D frag_more (2 * insn_len_words); > + bfd_putl16 ((bfd_vma) bin, frag); > + break; > + case V_PUSHM: /* Exemplar: pushm */ > + case V_POPM: /* Exemplar: popm */ > + l2 =3D get_operand (); > + bad_operand =3D > + !msp430_srcoperand (&op1, l1, IMM_RANGE_REPETITION_COUNT); > + bad_operand |=3D !msp430_dstoperand (&op2, l2, IMM_RANGE_INT20); > + if (bad_operand) > + break; /* An error occurred. All warnings were done before. */ > + > + if (!OP_HAS_IMMEDIATE (op1)) > { > - as_bad (_("instruction requires label sans '$'")); > + as_bad (_("bad operand [%s]"), l1); > + break; > } > - else > + > + if (op_width !=3D ADDR_OP) > + bin |=3D (1 << 8); > + bin |=3D ((op1.exp.X_add_number - 1) & 0x000F) << 4; > + > + if (OP_HAS_IMMEDIATE (op2)) > { > - as_bad (_ > - ("instruction requires label or value in range -511:512")); > + as_bad (_("bad operand [%s]"), l2); > + break; > } > - dwarf2_emit_insn (2 * __is); > + if (opcode_variant (opcode) =3D=3D V_POPM) > + bin |=3D (op2.reg - op1.exp.X_add_number + 1) & 0x000F; > + else > + bin |=3D op2.reg; > + > + insn_len_words =3D 1; > + frag =3D frag_more (2 * insn_len_words); > + bfd_putl16 ((bfd_vma) bin, frag); > break; > } > - else > + break; > + case FMT_X_ADDRESS: /* Exemplar: adda, mova */ > + /* mova, adda, suba, cmpa */ > + l1 =3D get_operand (); > + l2 =3D get_operand (); > + bad_operand =3D !msp430_srcoperand (&op1, l1, IMM_RANGE_INT20); > + bad_operand |=3D !msp430_dstoperand (&op2, l2, IMM_RANGE_INT20); > + if (bad_operand) > + break; /* Error in operand. */ > + > + msp430_address_substitute_CG (opcode, &op1); > + > + insn_len_words =3D 1 + op1.ol + op2.ol; > + frag =3D frag_more (insn_len_words * 2); > + where =3D frag - frag_now->fr_literal; > + bin =3D opcode->bin_opcode; /* remove WB/AL bits */ > + if (opcode_variant (opcode) =3D=3D V_MOVA) /* Exemplar: mova */ > { > - as_bad (_("instruction requires label")); > + if (!OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AM_Register) > + { /* Rsrc */ > + bin |=3D op1.reg << 8; > + if (op2.am !=3D AM_Indexed) > + { > + /* mova Rsrc, Rdst */ > + bin |=3D 0x00c0 | op2.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else > + { > + fixup =3D FX_A20D; > + gas_assert (op2.am =3D=3D AM_Indexed); > + if (op2.reg =3D=3D REGNO_CG1) /* AM_Absolute */ > + bin |=3D 0x0060; > + else > + { > + /* mova Rsrc, z16(Rdst) */ > + bin |=3D 0x0070 | op2.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + fixup =3D FX_A16; > + } > + bfd_putl16 ((bfd_vma) bin, frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + record_fixup (where, 2, op_width, &op2, fixup); > + } > + } > + else if (!OP_HAS_IMMEDIATE (op2) && op2.am =3D=3D AM_Register) > + { /* Rdst */ > + fixup =3D FX_INVALID; > + if (!OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AMs_IndirectRegister) > + { > + /* mova @Rsrc, Rdst */ > + bin |=3D 0x0000 | op1.reg << 8 | op2.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else if (!OP_HAS_IMMEDIATE (op1) > + && op1.am =3D=3D AMs_IndirectAutoIncrement) > + { > + /* mova @Rsrc+, Rdst */ > + bin |=3D 0x0010 | op1.reg << 8 | op2.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else if (OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AM_Indexed) > + { > + if (op1.reg =3D=3D REGNO_CG1) /* AM_Absolute */ > + { > + /* mova &abs20, Rdst */ > + bin |=3D 0x0020 | op2.reg; > + fixup =3D FX_A20S; > + } > + else /* AM_Symbolic or AM_Indexed */ > + { > + /* mova z16(Rsrc), Rdst */ > + bin |=3D 0x0030 | op1.reg << 8 | op2.reg; > + fixup =3D FX_A16; > + } > + bfd_putl16 ((bfd_vma) bin, frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + } > + else if (OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AMs_Immediate) > + { > + /* mova #imm20, Rdst */ > + bin |=3D 0x0080 | op2.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + fixup =3D FX_A20S; > + } > + else > + as_bad (_ > + ("source operand address mode %d not allowed with mova instruction"), > + op1.am); > + if (fixup !=3D FX_INVALID) > + record_fixup (where, 2, op_width, &op1, fixup); > + } > + else > + as_bad (_("unsupported operands for mova: %s, %s"), l1, l2); > break; > } > - break; > - > - case 4: /* Extended jumps. */ > - if (!msp430_enable_polys) > + else /* Exemplar: adda */ > + /* adda, suba, cmpa */ > { > - as_bad (_("polymorphs are not enabled. Use -mP option to enable.")); > + if (!OP_HAS_IMMEDIATE (op2) && op2.am =3D=3D AM_Register) > + { > + if (!OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AM_Register) > + { /* Rsrc, Rdst */ > + bin |=3D 0x0040 | op1.reg << 8 | op2.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else if (OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AMs_Immediate) > + { > + /* #imm20, Rdst */ > + bin |=3D 0x0080 | op2.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + record_fixup (where, 2, op_width, &op1, FX_A20S); > + } > + else > + as_bad (_ > + ("source operand address mode not allowed with %s instruction"), > + opcode->name); > + } > + else > + as_bad (_ > + ("destination operand address mode not allowed with %s instruction= "), > + opcode->name); > break; > } > -=09 > - line =3D extract_operand (line, l1, sizeof (l1)); > - if (l1[0]) > + break; > + > + case FMT_X_EMULATED: /* Extended emulated. */ > + switch (opcode_variant (opcode)) > { > - char *m =3D l1; > - expressionS exp; > + case V_NONE: /* Exemplar: popx */ > + /* single operand instruction emulated with Extended type 1 (double o= perand) instructions. */ > + l1 =3D get_operand (); > + if (!msp430_dstoperand (&op1, l1, IMM_RANGE_INT20)) > + break; >=20=20 > - /* Ignore absolute addressing. make it PC relative anyway. */ > - if (*m =3D=3D '#' || *m =3D=3D '$') > - m++; > + if (msp430x_repeats) > + { > + if ((bin >> 20) && 0x3 =3D=3D 1) > + { > + as_bad (_("%s instruction is not repeatable"), > + opcode->name); > + msp430x_repeats =3D 0; > + break; > + } > + if (OP_HAS_IMMEDIATE (op1)) > + { > + as_bad (_ > + ("Repeated instruction must have register mode operand")); > + msp430x_repeats =3D 0; > + break; > + } > + bin |=3D msp430x_repeats; > + msp430x_repeats =3D 0; > + } >=20=20 > - parse_exp (m, & exp); > - if (exp.X_op =3D=3D O_symbol) > + bin |=3D (op1.reg | (op1.am << 7)) << 16; > + insn_len_words =3D 2 + op1.ol; > + frag =3D frag_more (2 * insn_len_words); > + where =3D frag - frag_now->fr_literal; > + bfd_putl32 ((bfd_vma) bin, frag); > + > + if (OP_HAS_IMMEDIATE (op1)) > { > - /* Relaxation required. */ > - struct rcodes_s rc =3D msp430_rcodes[opcode->insn_opnumb]; > - > - /* The parameter to dwarf2_emit_insn is actually the offset to th= e start > - of the insn from the fix piece of instruction that was emitted. > - Since next fragments may have variable size we tie debug info > - to the beginning of the instruction. */ > - frag =3D frag_more (8); > - dwarf2_emit_insn (0); > - bfd_putl16 ((bfd_vma) rc.sop, frag); > - frag =3D frag_variant (rs_machine_dependent, 8, 2, > - ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */ > - exp.X_add_symbol, > - 0, /* Offset is zero if jump dist less than 1K. */ > - (char *) frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 4); > + record_fixup (where, 2, op_width, &op1, FX_X20D); > + } > + break; > + case V_MOVA: /* Exemplar clra: ops =3D #0, dst=3DRdst */ > + l1 =3D get_operand (); > + if (!msp430_dstoperand (&op1, l1, IMM_RANGE_INT20)) > + break; > + /* Technically as an emulated instruction the destination > + * could also be z16(Rdst) or &abs20, but the ISA > + * description specifies only Rdst. Use the real mova #0 > + * for the others. */ > + if (OP_HAS_IMMEDIATE (op1)) > + { > + as_bad (_("%s operand must be register"), opcode->name); > break; > } > - } > + insn_len_words =3D 1; > + frag =3D frag_more (insn_len_words * 2); > + where =3D frag - frag_now->fr_literal; > + bin |=3D op1.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + break; > + case V_X_SHIFT: /* Exemplar: rlax */ > + { > + /* Shift instruction. */ > + l1 =3D get_operand (); > + if (!msp430_srcoperand (&op1, l1, IMM_RANGE_INT20)) > + break; > + if (!convert_operand_to_dst (&op2, &op1, l1)) > + break; >=20=20 > - as_bad (_("instruction requires label")); > - break; > + if (msp430x_repeats && OP_HAS_IMMEDIATE (op2)) > + { > + as_bad (_ > + ("Repeated instruction must have register mode operands")); > + msp430x_repeats =3D 0; > + break; > + } > + bin |=3D msp430x_repeats; > + msp430x_repeats =3D 0; >=20=20 > - case 5: /* Emulated extended branches. */ > - if (!msp430_enable_polys) > - { > - as_bad (_("polymorphs are not enabled. Use -mP option to enable.")); > - break; > - } > - line =3D extract_operand (line, l1, sizeof (l1)); > - if (l1[0]) > - { > - char * m =3D l1; > - expressionS exp; > + bin |=3D > + (op2. > + reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)) << 16; > + > + insn_len_words =3D 2 + op1.ol + op2.ol; /* insn size in words. */ > + frag =3D frag_more (2 * insn_len_words); > + where =3D frag - frag_now->fr_literal; > + bfd_putl32 ((bfd_vma) bin, frag); >=20=20 > - /* Ignore absolute addressing. make it PC relative anyway. */ > - if (*m =3D=3D '#' || *m =3D=3D '$') > - m++; > + if (OP_HAS_IMMEDIATE (op1)) > + { > + bfd_putl16 ((bfd_vma) ZEROS, frag + 4); > + record_fixup (where, 2, op_width, &op1, FX_X20S); > + } >=20=20 > - parse_exp (m, & exp); > - if (exp.X_op =3D=3D O_symbol) > + if (OP_HAS_IMMEDIATE (op2)) > + { > + bfd_putl16 ((bfd_vma) ZEROS, > + frag + 4 + ((insn_len_words =3D=3D 4) ? 2 : 0)); > + record_fixup (where, 2, op_width, &op2, OP_HAS_IMMEDIATE (op1) ? FX_X2= 0D2 : FX_X20D); > + } > + } > + break; > + case V_RETA: /* Exemplar: reta */ > + if (msp430x_repeats) > { > - /* Relaxation required. */ > - struct hcodes_s hc =3D msp430_hcodes[opcode->insn_opnumb]; > - > - frag =3D frag_more (8); > - dwarf2_emit_insn (0); > - bfd_putl16 ((bfd_vma) hc.op0, frag); > - bfd_putl16 ((bfd_vma) hc.op1, frag+2); > - > - frag =3D frag_variant (rs_machine_dependent, 8, 2, > - ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */ > - exp.X_add_symbol, > - 0, /* Offset is zero if jump dist less than 1K. */ > - (char *) frag); > + as_bad (_("%s instruction is not repeatable"), opcode->name); > + msp430x_repeats =3D 0; > break; > } > - } > + bin =3D opcode->bin_opcode; /* remove WB/AL bits */ > + insn_len_words =3D 1; > + frag =3D frag_more (2 * insn_len_words); > + bfd_putl16 ((bfd_vma) bin, frag); > + break; > + case V_EMU_ADDR: /* Exemplar: incda */ > + /* incda, decda, tsta */ > + if (msp430x_repeats) > + { > + as_bad (_("%s instruction is not repeatable"), opcode->name); > + msp430x_repeats =3D 0; > + break; > + } > + bin =3D opcode->bin_opcode; /* remove WB/AL bits */ > + l1 =3D get_operand (); > + if (!msp430_dstoperand (&op1, l1, IMM_RANGE_INT20)) > + break; >=20=20 > - as_bad (_("instruction requires label")); > + insn_len_words =3D 1; > + if (!OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AM_Register) > + { > + frag =3D frag_more (2 * insn_len_words); > + bin |=3D op1.reg; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else > + as_bad (_ > + ("destination operand address mode not allowed with %s instruction= "), > + opcode->name); > + break; > + case V_BRA: /* Exemplar: bra */ > + /* bra, emulated with Address type instruction */ > + if (msp430x_repeats) > + { > + as_bad (_("%s instruction is not repeatable"), opcode->name); > + msp430x_repeats =3D 0; > + break; > + } > + > + bin =3D opcode->bin_opcode; /* remove WB/AL bits */ > + l1 =3D get_operand (); > + if (!msp430_srcoperand (&op1, l1, IMM_RANGE_INT20)) > + break; /* Error in operand. */ > + msp430_substitute_CG (&op1, ADDR_OP, 0); > + > + insn_len_words =3D 1 + op1.ol; > + frag =3D frag_more (insn_len_words * 2); > + where =3D frag - frag_now->fr_literal; > + fixup =3D FX_INVALID; > + if (!OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AM_Register) > + { > + /* mova Rsrc, PC */ > + bin |=3D 0x00C0 | op1.reg << 8; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else if (!OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AMs_IndirectRegiste= r) > + { > + /* mova @Rsrc, PC */ > + bin |=3D 0x0000 | op1.reg << 8; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else if (!OP_HAS_IMMEDIATE (op1) > + && op1.am =3D=3D AMs_IndirectAutoIncrement) > + { > + /* mova @Rsrc+, PC */ > + bin |=3D 0x0010 | op1.reg << 8; > + bfd_putl16 ((bfd_vma) bin, frag); > + } > + else if (OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AM_Indexed) > + { > + if (op1.reg =3D=3D REGNO_CG1) > + { > + /* mova &abs20, PC */ > + bin |=3D 0x0020; > + fixup =3D FX_A20S_W; > + } > + else > + { > + /* mova z16(Rsrc), PC */ > + bin |=3D 0x0030 | op1.reg << 8; > + fixup =3D FX_A16; > + } > + bfd_putl16 ((bfd_vma) bin, frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + } > + else if (OP_HAS_IMMEDIATE (op1) && op1.am =3D=3D AMs_Immediate) > + { > + /* mova #imm20, Rdst */ > + bin |=3D 0x0080; > + bfd_putl16 ((bfd_vma) bin, frag); > + bfd_putl16 ((bfd_vma) ZEROS, frag + 2); > + fixup =3D FX_A20S_W; > + } > + else > + as_bad (_ > + ("source operand address mode not allowed with bra instruction")); > + if (fixup !=3D FX_INVALID) > + record_fixup (where, 2, op_width, &op1, fixup); > + } > break; >=20=20 > default: > as_bad (_("Illegal instruction or not implemented opcode.")); > } >=20=20 > - input_line_pointer =3D line; > + if (0 < insn_len_words && 0 =3D=3D had_errors ()) > + dwarf2_emit_insn (2 * insn_len_words); > + > + if (l1) > + xfree (l1); > + if (l2) > + xfree (l2); > + > return 0; > } >=20=20 > void > -md_assemble (char * str) > +md_assemble (char *str) > { > - struct msp430_opcode_s * opcode; > - char cmd[32]; > - unsigned int i =3D 0; > - > - str =3D skip_space (str); /* Skip leading spaces. */ > - str =3D extract_cmd (str, cmd, sizeof (cmd)); > - > - while (cmd[i] && i < sizeof (cmd)) > - { > - char a =3D TOLOWER (cmd[i]); > - cmd[i] =3D a; > - i++; > - } > - > - if (!cmd[0]) > + struct msp430_opcode_s const *opcode; > + char *cmda; > + char *cmd; > + int i =3D 0; > + int cmd_length; > + > + while (ISSPACE (*str)) > + ++str; > + cmd =3D str; > + while (*str && (!ISSPACE (*str)) && '.' !=3D *str) > + ++str; > + cmd_length =3D str - cmd; > + if (0 =3D=3D cmd_length) > { > as_bad (_("can't find opcode ")); > return; > } >=20=20 > - opcode =3D (struct msp430_opcode_s *) hash_find (msp430_hash, cmd); > + cmda =3D alloca (1 + cmd_length); > + do > + cmda[i] =3D TOLOWER (cmd[i]); > + while (++i < cmd_length); > + cmda[i] =3D 0; > + > + opcode =3D (struct msp430_opcode_s const *) hash_find (msp430_hash, cm= da); >=20=20 > if (opcode =3D=3D NULL) > { > - as_bad (_("unknown opcode `%s'"), cmd); > + as_bad (_("unknown opcode `%s'"), cmda); > + return; > + } > + > + if (msp430_cpu < MSP430_CPU_MSP430X && opcode_format (opcode) >=3D FMT= _X) > + { > + as_bad (_("Extended instruction (%s) requires 430X-based mcu"), > + opcode->name); > return; > } >=20=20 > { > - char *__t =3D input_line_pointer; > + char *t =3D input_line_pointer; >=20=20 > msp430_operands (opcode, str); > - input_line_pointer =3D __t; > + input_line_pointer =3D t; > } > } >=20=20 > @@ -1857,105 +2642,49 @@ md_section_align (asection * seg, valueT addr) > long > md_pcrel_from_section (fixS * fixp, segT sec) > { > + long rv; > if (fixp->fx_addsy !=3D (symbolS *) NULL > && (!S_IS_DEFINED (fixp->fx_addsy) > || (S_GET_SEGMENT (fixp->fx_addsy) !=3D sec))) > return 0; > - > - return fixp->fx_frag->fr_address + fixp->fx_where; > -} > - > -/* Replaces standard TC_FORCE_RELOCATION_LOCAL. > - Now it handles the situation when relocations > - have to be passed to linker. */ > -int > -msp430_force_relocation_local(fixS *fixp) > -{ > - if (msp430_enable_polys > - && !msp430_enable_relax) > - return 1; > + if (fixp->fx_r_type =3D=3D BFD_RELOC_MSP430_10_PCREL) > + /* The only real PC-relative operand */ > + rv =3D fixp->fx_frag->fr_address + fixp->fx_where; > else > - return (!fixp->fx_pcrel > - || generic_force_reloc(fixp)); > + /* NB: 430X relocations/fixups do additional adjustments to > + * account for the value not being written at "where", which > + * instead points to the extension word. Those are independent of > + * pcrel so do not belong here. */ > + rv =3D fixp->fx_where - fixp->fx_dot_value; > + return rv; > } >=20=20 > - > /* GAS will call this for each fixup. It should store the correct > value in the object file. */ > void > md_apply_fix (fixS * fixp, valueT * valuep, segT seg) > { > - unsigned char * where; > + unsigned char *where; > unsigned long insn; > long value; >=20=20 > + value =3D *valuep; > if (fixp->fx_addsy =3D=3D (symbolS *) NULL) > - { > - value =3D *valuep; > - fixp->fx_done =3D 1; > - } > - else if (fixp->fx_pcrel) > + fixp->fx_done =3D 1; > + else if (fixp->fx_pcrel && fixp->fx_addsy !=3D (symbolS *)NULL) > { > segT s =3D S_GET_SEGMENT (fixp->fx_addsy); > - > - if (fixp->fx_addsy && (s =3D=3D seg || s =3D=3D absolute_section)) > - { > - /* FIXME: We can appear here only in case if we perform a pc > - relative jump to the label which is i) global, ii) locally > - defined or this is a jump to an absolute symbol. > - If this is an absolute symbol -- everything is OK. > - If this is a global label, we've got a symbol value defined > - twice: > - 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol off= set > - from this section start > - 2. *valuep will contain the real offset from jump insn to= the > - label > - So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep); > - will be incorrect. Therefore remove s_get_value. */ > - value =3D /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep; > - fixp->fx_done =3D 1; > - } > - else > - value =3D *valuep; > - } > - else > - { > - value =3D fixp->fx_offset; > - > - if (fixp->fx_subsy !=3D (symbolS *) NULL) > - { > - if (S_GET_SEGMENT (fixp->fx_subsy) =3D=3D absolute_section) > - { > - value -=3D S_GET_VALUE (fixp->fx_subsy); > - fixp->fx_done =3D 1; > - } > - else > - { > - /* We don't actually support subtracting a symbol. */ > - as_bad_where (fixp->fx_file, fixp->fx_line, > - _("expression too complex")); > - } > - } > + fixp->fx_done =3D (s =3D=3D seg || s =3D=3D absolute_section); > } > + if (fixp->fx_subsy !=3D (symbolS *) NULL) > + as_bad_where (fixp->fx_file, fixp->fx_line, _("expression too comple= x")); >=20=20 > fixp->fx_no_overflow =3D 1; >=20=20 > - /* if polymorphs are enabled and relax disabled.=20 > - do not kill any relocs and pass them to linker. */ > - if (msp430_enable_polys=20 > - && !msp430_enable_relax) > - { > - if (!fixp->fx_addsy || (fixp->fx_addsy=20 > - && S_GET_SEGMENT (fixp->fx_addsy) =3D=3D absolute_section)) > - fixp->fx_done =3D 1; /* It is ok to kill 'abs' reloc. */ > - else > - fixp->fx_done =3D 0; > - } > - > if (fixp->fx_done) > { > /* Fetch the instruction, insert the fully resolved operand > - value, and stuff the instruction back again. */ > + value, and stuff the instruction back again. */ >=20=20 > where =3D (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_w= here; >=20=20 > @@ -1963,68 +2692,210 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT= seg) >=20=20 > switch (fixp->fx_r_type) > { > + case BFD_RELOC_MSP430X_PCREL_D: > + case BFD_RELOC_MSP430X_PCREL_INDXD: > + /* operand located 2 bytes after where */ > + value -=3D 2; > + break; > + case BFD_RELOC_MSP430X_PCREL_SRC: > + case BFD_RELOC_MSP430X_PCREL_SRC_BYTE: > + case BFD_RELOC_MSP430X_PCREL_DST: > + case BFD_RELOC_MSP430X_PCREL_DST_BYTE: > + /* operand located 4 bytes after where */ > + value -=3D 4; > + break; > + case BFD_RELOC_MSP430X_PCREL_DST_2ND: > + case BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE: > + /* operand located 6 bytes after where */ > + value -=3D 6; > + break; > + default: > + break; > + } > + > + switch (fixp->fx_r_type) > + { > + case BFD_RELOC_32: /* Required; used for elf header? */ > + bfd_putl32 ((bfd_vma) MASK_32 (value), where); > + break; > + > + case BFD_RELOC_MSP430_10: > case BFD_RELOC_MSP430_10_PCREL: > - if (value & 1) > + if (MSP430_ODD (value)) > as_bad_where (fixp->fx_file, fixp->fx_line, > _("odd address operand: %ld"), value); >=20=20 > + /* If we get here at all, it's because the operand > + * expression involved a PC-relative calculation, but the > + * final value could be determined without resolving an > + * external symbol. That value does not account for the > + * fact that the PC will have been incremented by two at the > + * point where the offset is applied. Do that now. */ > + value -=3D 2; > + > /* Jumps are in words. */ > value >>=3D 1; > - --value; /* Correct PC. */ >=20=20 > - if (value < -512 || value > 511) > + if (!MSP430_S10_IN_RANGE (value)) > as_bad_where (fixp->fx_file, fixp->fx_line, > _("operand out of range: %ld"), value); >=20=20 > - value &=3D 0x3ff; /* get rid of extended sign */ > + value =3D MASK_10 (value); /* get rid of extended sign */ > bfd_putl16 ((bfd_vma) (value | insn), where); > break; >=20=20 > - case BFD_RELOC_MSP430_RL_PCREL: > + case BFD_RELOC_MSP430_16: > case BFD_RELOC_MSP430_16_PCREL: > - if (value & 1) > + if (MSP430_ODD (value)) > as_bad_where (fixp->fx_file, fixp->fx_line, > - _("odd address operand: %ld"), value); > + _("odd operand: %ld"), value); > + /*FALLTHRU*/; > + case BFD_RELOC_16: /* Required; used for elf header? */ > + case BFD_RELOC_MSP430_16_BYTE: > + case BFD_RELOC_MSP430_16_PCREL_BYTE: > + if (!MSP430_16_IN_RANGE (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("operand out of range: %ld"), value); > + bfd_putl16 ((bfd_vma) MASK_16 (value), where); > + break; >=20=20 > - /* Nothing to be corrected here. */ > - if (value < -32768 || value > 65536) > + case BFD_RELOC_MSP430X_SRC: > + case BFD_RELOC_MSP430X_PCREL_SRC: > + if (MSP430_ODD (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("odd operand: %ld"), value); > + /*FALLTHRU*/; > + case BFD_RELOC_MSP430X_SRC_BYTE: > + case BFD_RELOC_MSP430X_PCREL_SRC_BYTE: > + if (!MSP430_20_IN_RANGE (value)) > as_bad_where (fixp->fx_file, fixp->fx_line, > _("operand out of range: %ld"), value); > + value =3D MASK_20 (value); > + bfd_putl16 ((bfd_vma) (bfd_getl16 (where) & 0xf87f) | > + ((value >> 9) & 0x0780), where); > + bfd_putl16 ((bfd_vma) MASK_16 (value), where + 4); > + break; >=20=20 > - value &=3D 0xffff; /* Get rid of extended sign. */ > - bfd_putl16 ((bfd_vma) value, where); > + case BFD_RELOC_MSP430X_DST: > + case BFD_RELOC_MSP430X_PCREL_DST: > + if (MSP430_ODD (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("odd operand: %ld"), value); > + /*FALLTHRU*/; > + case BFD_RELOC_MSP430X_DST_BYTE: > + case BFD_RELOC_MSP430X_PCREL_DST_BYTE: > + if (!MSP430_20_IN_RANGE (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("operand out of range: %ld"), value); > + value =3D MASK_20 (value); > + bfd_putl16 ((bfd_vma) (bfd_getl16 (where) & 0xfff0) | > + ((value >> 16) & 0x000f), where); > + bfd_putl16 ((bfd_vma) MASK_16 (value), where + 4); > break; >=20=20 > - case BFD_RELOC_MSP430_16_PCREL_BYTE: > - /* Nothing to be corrected here. */ > - if (value < -32768 || value > 65536) > + case BFD_RELOC_MSP430X_DST_2ND: > + case BFD_RELOC_MSP430X_PCREL_DST_2ND: > + if (MSP430_ODD (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("odd operand: %ld"), value); > + /*FALLTHRU*/; > + case BFD_RELOC_MSP430X_DST_2ND_BYTE: > + case BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE: > + if (!MSP430_20_IN_RANGE (value)) > as_bad_where (fixp->fx_file, fixp->fx_line, > _("operand out of range: %ld"), value); > + value =3D MASK_20 (value); > + bfd_putl16 ((bfd_vma) (bfd_getl16 (where) & 0xfff0) | > + ((value >> 16) & 0x000f), where); > + bfd_putl16 ((bfd_vma) MASK_16 (value), where + 6); > + break; >=20=20 > - value &=3D 0xffff; /* Get rid of extended sign. */ > - bfd_putl16 ((bfd_vma) value, where); > + case BFD_RELOC_MSP430X_S: > + if (MSP430_ODD (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("odd operand: %ld"), value); > + /*FALLTHRU*/; > + case BFD_RELOC_MSP430X_S_BYTE: > + if (!MSP430_20_IN_RANGE (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("operand out of range: %ld"), value); > + value =3D MASK_20 (value); > + bfd_putl16 ((bfd_vma) (bfd_getl16 (where) & 0xf0ff) | > + ((value >> 8) & 0x0f00), where); > + bfd_putl16 ((bfd_vma) MASK_16 (value), where + 2); > break; >=20=20 > - case BFD_RELOC_32: > - bfd_putl16 ((bfd_vma) value, where); > + case BFD_RELOC_MSP430X_D: > + case BFD_RELOC_MSP430X_PCREL_D: > + if (MSP430_ODD (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("odd operand: %ld"), value); > + /*FALLTHRU*/; > + case BFD_RELOC_MSP430X_D_BYTE: > + if (!MSP430_20_IN_RANGE (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("operand out of range: %ld"), value); > + value =3D MASK_20 (value); > + bfd_putl16 ((bfd_vma) (bfd_getl16 (where) & 0xfff0) | > + ((value >> 16) & 0x000f), where); > + /* 16 least-significant bits */ > + bfd_putl16 ((bfd_vma) MASK_16 (value), where + 2); > break; >=20=20 > - case BFD_RELOC_MSP430_16: > - case BFD_RELOC_16: > - case BFD_RELOC_MSP430_16_BYTE: > - value &=3D 0xffff; > - bfd_putl16 ((bfd_vma) value, where); > + case BFD_RELOC_MSP430X_PCREL_INDXD: > + if (MSP430_ODD (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("odd operand: %ld"), value); > + /*FALLTHRU*/; > + case BFD_RELOC_MSP430X_INDXD: > + if (!MSP430_S16_IN_RANGE (value)) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("operand out of range: %ld"), value); > + bfd_putl16 ((bfd_vma) MASK_16 (value), where + 2); > break; >=20=20 > + case BFD_RELOC_MSP430_RL_PCREL: > + case BFD_RELOC_MSP430_2X_PCREL: > default: > - as_fatal (_("line %d: unknown relocation type: 0x%x"), > - fixp->fx_line, fixp->fx_r_type); > + as_fatal (_("line %d: unknown relocation type: 0x%x (%s)"), > + fixp->fx_line, fixp->fx_r_type, > + bfd_get_reloc_code_name (fixp->fx_r_type)); > break; > } > } > else > { > + int reloc_is_pcrel =3D > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_D || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_DST || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_DST_2ND || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_DST_BYTE || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_INDXD || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_SRC || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430X_PCREL_SRC_BYTE || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430_10_PCREL || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430_16_PCREL || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430_16_PCREL_BYTE || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430_2X_PCREL || > + fixp->fx_r_type =3D=3D BFD_RELOC_MSP430_RL_PCREL; > + > + /* TODO: This is useless; the fx_addnumber field is unused. > + Probably fx_offset was desired, as that becames the addend in > + the relocation. Not changed at this time, because currently > + the BFD code repeats the adjustments that were made above. */ > fixp->fx_addnumber =3D value; > + /* If the value we calculate is not the same as is going into > + * the relocation, the expression semantics is not preserved. > + * This can happen with symbol-. where symbol is in a different > + * section. We could fix this by updating the offset in > + * relocation, although object file backwards compatibility has > + * to be validated. */ > + if (value !=3D (long)fixp->fx_offset && fixp->fx_pcrel && !reloc_i= s_pcrel) > + as_bad_where (fixp->fx_file, fixp->fx_line, > + _("expression %d too complex for %s (offset %ld will be %ld)"), > + fixp->fx_pcrel, bfd_get_reloc_code_name (fixp->fx_r_type), > + value, fixp->fx_offset); > } > } >=20=20 > @@ -2040,7 +2911,7 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT se= g) > arelent * > tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp) > { > - arelent * reloc; > + arelent *reloc; >=20=20 > reloc =3D xmalloc (sizeof (arelent)); >=20=20 > @@ -2066,230 +2937,19 @@ tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, f= ixS * fixp) > return reloc; > } >=20=20 > -int > -md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, > - asection * segment_type ATTRIBUTE_UNUSED) > -{ > - if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) =3D=3D segmen= t_type) > - { > - /* This is a jump -> pcrel mode. Nothing to do much here. > - Return value =3D=3D 2. */ > - fragP->fr_subtype =3D > - ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10); > - } > - else if (fragP->fr_symbol) > - { > - /* Its got a segment, but its not ours. Even if fr_symbol is in > - an absolute segment, we don't know a displacement until we link > - object files. So it will always be long. This also applies to > - labels in a subsegment of current. Liker may relax it to short > - jump later. Return value =3D=3D 8. */ > - fragP->fr_subtype =3D > - ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD); > - } > - else > - { > - /* We know the abs value. may be it is a jump to fixed address. > - Impossible in our case, cause all constants already handled. */ > - fragP->fr_subtype =3D > - ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF); > - } > - > - return md_relax_table[fragP->fr_subtype].rlx_length; > -} > - > void > md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, > asection * sec ATTRIBUTE_UNUSED, > - fragS * fragP) > + fragS * fragP ATTRIBUTE_UNUSED) > { > - char * where =3D 0; > - int rela =3D -1; > - int i; > - struct rcodes_s * cc =3D NULL; > - struct hcodes_s * hc =3D NULL; > - > - switch (fragP->fr_subtype) > - { > - case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10): > - case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10): > - case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10): > - /* We do not have to convert anything here. > - Just apply a fix. */ > - rela =3D BFD_RELOC_MSP430_10_PCREL; > - break; > - > - case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD): > - case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF): > - /* Convert uncond branch jmp lab -> br lab. */ > - cc =3D & msp430_rcodes[7]; > - where =3D fragP->fr_literal + fragP->fr_fix; > - bfd_putl16 (cc->lop0, where); > - rela =3D BFD_RELOC_MSP430_RL_PCREL; > - fragP->fr_fix +=3D 2; > - break; > - > - case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD): > - case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF): > - { > - /* Other simple branches. */ > - int insn =3D bfd_getl16 (fragP->fr_opcode); > - > - insn &=3D 0xffff; > - /* Find actual instruction. */ > - for (i =3D 0; i < 7 && !cc; i++) > - if (msp430_rcodes[i].sop =3D=3D insn) > - cc =3D & msp430_rcodes[i]; > - if (!cc || !cc->name) > - as_fatal (_("internal inconsistency problem in %s: insn %04lx"), > - __FUNCTION__, (long) insn); > - where =3D fragP->fr_literal + fragP->fr_fix; > - bfd_putl16 (cc->lop0, where); > - bfd_putl16 (cc->lop1, where + 2); > - rela =3D BFD_RELOC_MSP430_RL_PCREL; > - fragP->fr_fix +=3D 4; > - } > - break; > - > - case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD): > - case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF): > - cc =3D & msp430_rcodes[6]; > - where =3D fragP->fr_literal + fragP->fr_fix; > - bfd_putl16 (cc->lop0, where); > - bfd_putl16 (cc->lop1, where + 2); > - bfd_putl16 (cc->lop2, where + 4); > - rela =3D BFD_RELOC_MSP430_RL_PCREL; > - fragP->fr_fix +=3D 6; > - break; > - > - case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10): > - { > - int insn =3D bfd_getl16 (fragP->fr_opcode + 2); > - > - insn &=3D 0xffff; > - for (i =3D 0; i < 4 && !hc; i++) > - if (msp430_hcodes[i].op1 =3D=3D insn) > - hc =3D &msp430_hcodes[i]; > - if (!hc || !hc->name) > - as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"), > - __FUNCTION__, (long) insn); > - rela =3D BFD_RELOC_MSP430_10_PCREL; > - /* Apply a fix for a first label if necessary. > - another fix will be applied to the next word of insn anyway. */ > - if (hc->tlab =3D=3D 2) > - fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, > - fragP->fr_offset, TRUE, rela); > - fragP->fr_fix +=3D 2; > - } > - > - break; > - > - case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD): > - case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF): > - { > - int insn =3D bfd_getl16 (fragP->fr_opcode + 2); > - > - insn &=3D 0xffff; > - for (i =3D 0; i < 4 && !hc; i++) > - if (msp430_hcodes[i].op1 =3D=3D insn) > - hc =3D & msp430_hcodes[i]; > - if (!hc || !hc->name) > - as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"), > - __FUNCTION__, (long) insn); > - rela =3D BFD_RELOC_MSP430_RL_PCREL; > - where =3D fragP->fr_literal + fragP->fr_fix; > - bfd_putl16 (hc->lop0, where); > - bfd_putl16 (hc->lop1, where + 2); > - bfd_putl16 (hc->lop2, where + 4); > - fragP->fr_fix +=3D 6; > - } > - break; > - > - default: > - as_fatal (_("internal inconsistency problem in %s: %lx"), > - __FUNCTION__, (long) fragP->fr_subtype); > - break; > - } > - > - /* Now apply fix. */ > - fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, > - fragP->fr_offset, TRUE, rela); > - /* Just fixed 2 bytes. */ > - fragP->fr_fix +=3D 2; > + gas_assert (0); > } >=20=20 > -/* Relax fragment. Mostly stolen from hc11 and mcore > - which arches I think I know. */ >=20=20 > -long > -msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP, > - long stretch ATTRIBUTE_UNUSED) > +int > +md_estimate_size_before_relax (fragS * fragp ATTRIBUTE_UNUSED, > + asection * seg ATTRIBUTE_UNUSED) > { > - long growth; > - offsetT aim =3D 0; > - symbolS *symbolP; > - const relax_typeS *this_type; > - const relax_typeS *start_type; > - relax_substateT next_state; > - relax_substateT this_state; > - const relax_typeS *table =3D md_relax_table; > - > - /* Nothing to be done if the frag has already max size. */ > - if (RELAX_STATE (fragP->fr_subtype) =3D=3D STATE_UNDEF > - || RELAX_STATE (fragP->fr_subtype) =3D=3D STATE_WORD) > - return 0; > - > - if (RELAX_STATE (fragP->fr_subtype) =3D=3D STATE_BITS10) > - { > - symbolP =3D fragP->fr_symbol; > - if (symbol_resolved_p (symbolP)) > - as_fatal (_("internal inconsistency problem in %s: resolved symbol"), > - __FUNCTION__); > - /* We know the offset. calculate a distance. */ > - aim =3D S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix; > - } > - > - if (!msp430_enable_relax) > - { > - /* Relaxation is not enabled. So, make all jump as long ones > - by setting 'aim' to quite high value. */ > - aim =3D 0x7fff; > - } > -=20=20 > - this_state =3D fragP->fr_subtype; > - start_type =3D this_type =3D table + this_state; > - > - if (aim < 0) > - { > - /* Look backwards. */ > - for (next_state =3D this_type->rlx_more; next_state;) > - if (aim >=3D this_type->rlx_backward || !this_type->rlx_backward) > - next_state =3D 0; > - else > - { > - /* Grow to next state. */ > - this_state =3D next_state; > - this_type =3D table + this_state; > - next_state =3D this_type->rlx_more; > - } > - } > - else > - { > - /* Look forwards. */ > - for (next_state =3D this_type->rlx_more; next_state;) > - if (aim <=3D this_type->rlx_forward || !this_type->rlx_forward) > - next_state =3D 0; > - else > - { > - /* Grow to next state. */ > - this_state =3D next_state; > - this_type =3D table + this_state; > - next_state =3D this_type->rlx_more; > - } > - } > - > - growth =3D this_type->rlx_length - start_type->rlx_length; > - if (growth !=3D 0) > - fragP->fr_subtype =3D this_state; > - return growth; > + gas_assert (0); > + return 0; > } > diff --git binutils-2.21.1a.orig/gas/config/tc-msp430.h binutils-2.21.1a/= gas/config/tc-msp430.h > index 2f7aea2..c653fbe 100644 > --- binutils-2.21.1a.orig/gas/config/tc-msp430.h > +++ binutils-2.21.1a/gas/config/tc-msp430.h > @@ -1,5 +1,5 @@ > /* This file is tc-msp430.h > - Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc. > + Copyright (C) 2002, 2004, 2005, 2007, 2012 Free Software Foundation, = Inc. >=20=20 > Contributed by Dmitry Diky >=20=20 > @@ -20,103 +20,38 @@ > Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA > 02110-1301, USA. */ >=20=20 > -#define TC_MSP430 > -/* By convention, you should define this macro in the `.h' file. For > - example, `tc-m68k.h' defines `TC_M68K'. You might have to use this > - if it is necessary to add CPU specific code to the object format > - file. */ > +#ifndef TC_MSP430 > +#define TC_MSP430 1 >=20=20 > #define TARGET_FORMAT "elf32-msp430" > -/* This macro is the BFD target name to use when creating the output > - file. This will normally depend upon the `OBJ_FMT' macro. */ > - > #define TARGET_ARCH bfd_arch_msp430 > -/* This macro is the BFD architecture to pass to `bfd_set_arch_mach'. = */ > - > -#define TARGET_MACH 0 > -/* This macro is the BFD machine number to pass to > - `bfd_set_arch_mach'. If it is not defined, GAS will use 0. */ >=20=20 > #define TARGET_BYTES_BIG_ENDIAN 0 > -/* You should define this macro to be non-zero if the target is big > - endian, and zero if the target is little endian. */ > +#define md_number_to_chars number_to_chars_littleendian >=20=20 > #define ONLY_STANDARD_ESCAPES > -/* If you define this macro, GAS will warn about the use of > - nonstandard escape sequences in a string. */ >=20=20 > #define md_operand(x) > -/* GAS will call this function for any expression that can not be > - recognized. When the function is called, `input_line_pointer' > - will point to the start of the expression. */ >=20=20 > -#define md_number_to_chars number_to_chars_littleendian > -/* This should just call either `number_to_chars_bigendian' or > - `number_to_chars_littleendian', whichever is appropriate. On > - targets like the MIPS which support options to change the > - endianness, which function to call is a runtime decision. On > - other targets, `md_number_to_chars' can be a simple macro. */ > +#define DOLLAR_DOT >=20=20 > +/* True at least until far pointers invalidate this: */ > #define WORKING_DOT_WORD > -/* > -`md_short_jump_size' > -`md_long_jump_size' > -`md_create_short_jump' > -`md_create_long_jump' > - If `WORKING_DOT_WORD' is defined, GAS will not do broken word > - processing (*note Broken words::.). Otherwise, you should set > - `md_short_jump_size' to the size of a short jump (a jump that is > - just long enough to jump around a long jmp) and > - `md_long_jump_size' to the size of a long jump (a jump that can go > - anywhere in the function), You should define > - `md_create_short_jump' to create a short jump around a long jump, > - and define `md_create_long_jump' to create a long jump. */ > - > -#define MD_APPLY_FIX3 > - > -#define TC_HANDLES_FX_DONE > - > -#undef RELOC_EXPANSION_POSSIBLE > -/* If you define this macro, it means that `tc_gen_reloc' may return > - multiple relocation entries for a single fixup. In this case, the > - return value of `tc_gen_reloc' is a pointer to a null terminated > - array. */ > - > -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) > -/* If you define this macro, it should return the offset between the > - address of a PC relative fixup and the position from which the PC > - relative adjustment should be made. On many processors, the base > - of a PC relative instruction is the next instruction, so this > - macro would return the length of an instruction. */ >=20=20 > -extern long md_pcrel_from_section (struct fix *, segT); > +/* Do not allow r3-2 to become r1 */ > +#define md_register_arithmetic 0 >=20=20 > #define LISTING_WORD_SIZE 2 > -/* The number of bytes to put into a word in a listing. This affects > - the way the bytes are clumped together in the listing. For > - example, a value of 2 might print `1234 5678' where a value of 1 > - would print `12 34 56 78'. The default value is 4. */ > - > -#define LEX_DOLLAR 0 > -/* MSP430 port does not use `$' as a logical line separator */ >=20=20 > +/* TBD: SF 3486339 */ > #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) =3D 0 > -/* An `.lcomm' directive with no explicit alignment parameter will > - use this macro to set P2VAR to the alignment that a request for > - SIZE bytes will have. The alignment is expressed as a power of > - two. If no alignment should take place, the macro definition > - should do nothing. Some targets define a `.bss' directive that is > - also affected by this macro. The default definition will set > - P2VAR to the truncated power of two of sizes up to eight bytes. */ >=20=20 > -#define md_relax_frag(SEG, FRAGP, STRETCH) \ > - msp430_relax_frag (SEG, FRAGP, STRETCH) > -extern long msp430_relax_frag (segT, fragS *, long); > +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) > +extern long md_pcrel_from_section (struct fix *, segT); >=20=20 > -#define TC_FORCE_RELOCATION_LOCAL(FIX) \ > - msp430_force_relocation_local(FIX) > -extern int msp430_force_relocation_local(struct fix *); > +#define MD_APPLY_SYM(FIXP) (0) >=20=20 > +/* Allow symbol-. to force PCREL relocations */ > +#define DIFF_EXPR_OK >=20=20 > -extern int msp430_enable_relax; > -extern int msp430_enable_polys; > +#endif /* TC_MSP430 */ > diff --git binutils-2.21.1a.orig/gas/doc/c-msp430.texi binutils-2.21.1a/g= as/doc/c-msp430.texi > index 09ce9f0..8b21450 100644 > --- binutils-2.21.1a.orig/gas/doc/c-msp430.texi > +++ binutils-2.21.1a/gas/doc/c-msp430.texi > @@ -30,12 +30,6 @@ >=20=20 > @item -m > select the mpu arch. Currently has no effect. > -@item -mP=20 > -enables polymorph instructions handler. > - > -@item -mQ=20 > -enables relaxation at assembly time. DANGEROUS! > - > @end table >=20=20 > @node MSP430 Syntax > diff --git binutils-2.21.1a.orig/gas/testsuite/gas/msp430/opcode.d binuti= ls-2.21.1a/gas/testsuite/gas/msp430/opcode.d > index 22df51c..297d3e1 100644 > --- binutils-2.21.1a.orig/gas/testsuite/gas/msp430/opcode.d > +++ binutils-2.21.1a/gas/testsuite/gas/msp430/opcode.d > @@ -5,41 +5,49 @@ >=20=20 > Disassembly of section .text: > 0+000 <[^>]*> 1b f3 and #1, r11 ;r3 As=3D=3D01 > -0+002 <[^>]*> 3a e3 inv r10 ; > +0+002 <[^>]*> 3a e3 inv r10=09=09 > 0+004 <[^>]*> 3b e0 ff 00 xor #255, r11 ;#0x00ff > 0+008 <[^>]*> 3c d2 bis #8, r12 ;r2 As=3D=3D11 > 0+00a <[^>]*> 3d b0 10 00 bit #16, r13 ;#0x0010 > 0+00e <[^>]*> 3e c0 a0 00 bic #160, r14 ;#0x00a0 > -0+012 <[^>]*> 0f 93 cmp #0, r15 ;r3 As=3D=3D00 > -0+014 <[^>]*> 1a 83 dec r10 ; > -0+016 <[^>]*> 0b 73 sbc r11 ; > -0+018 <[^>]*> 1c 53 inc r12 ; > +0+012 <[^>]*> 0f 93 tst r15=09=09 > +0+014 <[^>]*> 1a 83 dec r10=09=09 > +0+016 <[^>]*> 0b 73 sbc r11=09=09 > +0+018 <[^>]*> 1c 53 inc r12=09=09 > 0+01a <[^>]*> 2d 63 addc #2, r13 ;r3 As=3D=3D10 > -0+01c <[^>]*> 0e 12 push r14 ; > -0+01e <[^>]*> 3f 41 pop r15 ; > -0+020 <[^>]*> 8a 11 sxt r10 ; > -0+022 <[^>]*> 0b 11 rra r11 ; > -0+024 <[^>]*> 8c 10 swpb r12 ; > -0+026 <[^>]*> 0d 10 rrc r13 ; > +0+01c <[^>]*> 0e 12 push r14=09=09 > +0+01e <[^>]*> 3f 41 pop r15=09=09 > +0+020 <[^>]*> 8a 11 sxt r10=09=09 > +0+022 <[^>]*> 0b 11 rra r11=09=09 > +0+024 <[^>]*> 8c 10 swpb r12=09=09 > +0+026 <[^>]*> 0d 10 rrc r13=09=09 > 0+028 <[^>]*> 30 41 ret=09=09=09 > 0+02a <[^>]*> 31 40 00 00 mov #0, r1 ;#0x0000 > -0+02e <[^>]*> b0 12 00 00 call #0 ;#0x0000 > -0+032 <[^>]*> 1e 42 00 00 mov &0x0000,r14 ;0x0000 > -0+036 <[^>]*> 0f 4e mov r14, r15 ; > -0+038 <[^>]*> 0f 5f rla r15 ; > -0+03a <[^>]*> 0f 7f subc r15, r15 ; > -0+03c <[^>]*> 3f e3 inv r15 ; > -0+03e <[^>]*> b0 12 00 00 call #0 ;#0x0000 > -0+042 <[^>]*> 82 4e 00 00 mov r14, &0x0000 ; > -0+046 <[^>]*> 82 4f 00 00 mov r15, &0x0000 ; > -0+04a <[^>]*> 1e 42 00 00 mov &0x0000,r14 ;0x0000 > -0+04e <[^>]*> 0f 4e mov r14, r15 ; > -0+050 <[^>]*> 0f 5f rla r15 ; > -0+052 <[^>]*> 0f 7f subc r15, r15 ; > -0+054 <[^>]*> 3f e3 inv r15 ; > -0+056 <[^>]*> b0 12 00 00 call #0 ;#0x0000 > -0+05a <[^>]*> 82 4e 00 00 mov r14, &0x0000 ; > -0+05e <[^>]*> 82 4f 00 00 mov r15, &0x0000 ; > +0+02e <[^>]*> b0 12 00 00 call #0x0000=09 > +0+032 <[^>]*> 1e 42 00 00 mov &0x0000,r14=09 > +0+036 <[^>]*> 0f 4e mov r14, r15=09 > +0+038 <[^>]*> 0f 5f rla r15=09=09 > +0+03a <[^>]*> 0f 7f subc r15, r15=09 > +0+03c <[^>]*> 3f e3 inv r15=09=09 > +0+03e <[^>]*> b0 12 00 00 call #0x0000=09 > +0+042 <[^>]*> 82 4e 00 00 mov r14, &0x0000=09 > +0+046 <[^>]*> 82 4f 00 00 mov r15, &0x0000=09 > +0+04a <[^>]*> 1e 42 00 00 mov &0x0000,r14=09 > +0+04e <[^>]*> 0f 4e mov r14, r15=09 > +0+050 <[^>]*> 0f 5f rla r15=09=09 > +0+052 <[^>]*> 0f 7f subc r15, r15=09 > +0+054 <[^>]*> 3f e3 inv r15=09=09 > +0+056 <[^>]*> b0 12 00 00 call #0x0000=09 > +0+05a <[^>]*> 82 4e 00 00 mov r14, &0x0000=09 > +0+05e <[^>]*> 82 4f 00 00 mov r15, &0x0000=09 > 0+062 <[^>]*> 3f 40 f0 00 mov #240, r15 ;#0x00f0 > -0+066 <[^>]*> 30 40 00 00 br #0x0000 ; > -0+06a <[^>]*> 92 52 00 02 72 01 add &0x0200,&0x0172 ;0x0200 > +0+066 <[^>]*> 30 40 00 00 br #0x0000=09 > +0+06a <[^>]*> 92 52 00 02 72 01 add &0x0200,&0x0172=09 > +0+070 3a 40 f0 de mov #-8464, r10 ;#0xdef0 > +0+074 3b 40 bc 9a mov #-25924,r11 ;#0x9abc > +0+078 3c 40 78 56 mov #22136, r12 ;#0x5678 > +0+07c 3d 40 34 12 mov #4660, r13 ;#0x1234 > +0+080 3a 40 7b 00 mov #123, r10 ;#0x007b > +0+084 0b 43 clr r11=09=09 > +0+086 0c 43 clr r12=09=09 > +0+088 0d 43 clr r13=09=09 > diff --git binutils-2.21.1a.orig/gas/testsuite/gas/msp430/opcode.s binuti= ls-2.21.1a/gas/testsuite/gas/msp430/opcode.s > index b85a463..8fa444f 100644 > --- binutils-2.21.1a.orig/gas/testsuite/gas/msp430/opcode.s > +++ binutils-2.21.1a/gas/testsuite/gas/msp430/opcode.s > @@ -55,3 +55,19 @@ main: > ;; This next instruction triggered a bug which > ;; was fixed by a patch to msp430-dis.c on Jan 2, 2004 > add &0x200, &0x172 > + > +.global extract > + .type extract,@function > +extract:=09 > + mov #llo(0x123456789abcdef0), r10 > + mov #lhi(0x123456789abcdef0), r11 > + mov #hlo(0x123456789abcdef0), r12 > + mov #hhi(0x123456789abcdef0), r13 > +=09 > +.global extract0 > + .type extract,@function > +extract0: > + mov #llo(123), r10 > + mov #lhi(123), r11 > + mov #hlo(123), r12 > + mov #hhi(123), r13 > diff --git binutils-2.21.1a.orig/include/elf/msp430.h binutils-2.21.1a/in= clude/elf/msp430.h > index 44f5c51..ed6296a 100644 > --- binutils-2.21.1a.orig/include/elf/msp430.h > +++ binutils-2.21.1a/include/elf/msp430.h > @@ -1,5 +1,5 @@ > /* MSP430 ELF support for BFD. > - Copyright (C) 2002, 2003, 2004, 2010 Free Software Foundation, Inc. > + Copyright (C) 2002, 2003, 2004, 2010, 2012 Free Software Foundation, = Inc. > Contributed by Dmitry Diky >=20=20 > This file is part of BFD, the Binary File Descriptor library. > @@ -23,24 +23,6 @@ >=20=20 > #include "elf/reloc-macros.h" >=20=20 > -/* Processor specific flags for the ELF header e_flags field. */ > -#define EF_MSP430_MACH 0xff > - > -#define E_MSP430_MACH_MSP430x11 11 > -#define E_MSP430_MACH_MSP430x11x1 110 > -#define E_MSP430_MACH_MSP430x12 12 > -#define E_MSP430_MACH_MSP430x13 13 > -#define E_MSP430_MACH_MSP430x14 14 > -#define E_MSP430_MACH_MSP430x15 15 > -#define E_MSP430_MACH_MSP430x16 16 > -#define E_MSP430_MACH_MSP430x31 31 > -#define E_MSP430_MACH_MSP430x32 32 > -#define E_MSP430_MACH_MSP430x33 33 > -#define E_MSP430_MACH_MSP430x41 41 > -#define E_MSP430_MACH_MSP430x42 42 > -#define E_MSP430_MACH_MSP430x43 43 > -#define E_MSP430_MACH_MSP430x44 44 > - > /* Relocations. */ > START_RELOC_NUMBERS (elf_msp430_reloc_type) > RELOC_NUMBER (R_MSP430_NONE, 0) > @@ -50,9 +32,74 @@ START_RELOC_NUMBERS (elf_msp430_reloc_type) > RELOC_NUMBER (R_MSP430_16_PCREL, 4) > RELOC_NUMBER (R_MSP430_16_BYTE, 5) > RELOC_NUMBER (R_MSP430_16_PCREL_BYTE, 6) > - RELOC_NUMBER (R_MSP430_2X_PCREL, 7) > - RELOC_NUMBER (R_MSP430_RL_PCREL, 8) > + RELOC_NUMBER (R_MSP430_2X_PCREL, 7) /* obsolete */ > + RELOC_NUMBER (R_MSP430_RL_PCREL, 8) /* obsolete */ > + RELOC_NUMBER (R_MSP430X_SRC_BYTE, 9) > + RELOC_NUMBER (R_MSP430X_SRC, 10) > + RELOC_NUMBER (R_MSP430X_DST_BYTE, 11) > + RELOC_NUMBER (R_MSP430X_DST, 12) > + RELOC_NUMBER (R_MSP430X_DST_2ND_BYTE, 13) > + RELOC_NUMBER (R_MSP430X_DST_2ND, 14) > + RELOC_NUMBER (R_MSP430X_PCREL_SRC_BYTE, 15) > + RELOC_NUMBER (R_MSP430X_PCREL_SRC, 16) > + RELOC_NUMBER (R_MSP430X_PCREL_DST_BYTE, 17) > + RELOC_NUMBER (R_MSP430X_PCREL_DST, 18) > + RELOC_NUMBER (R_MSP430X_PCREL_DST_2ND, 19) > + RELOC_NUMBER (R_MSP430X_PCREL_DST_2ND_BYTE, 20) > + RELOC_NUMBER (R_MSP430X_S_BYTE, 21) > + RELOC_NUMBER (R_MSP430X_S, 22) > + RELOC_NUMBER (R_MSP430X_D_BYTE, 23) > + RELOC_NUMBER (R_MSP430X_D, 24) > + RELOC_NUMBER (R_MSP430X_PCREL_D, 25) > + RELOC_NUMBER (R_MSP430X_INDXD, 26) > + RELOC_NUMBER (R_MSP430X_PCREL_INDXD, 27) > + RELOC_NUMBER (R_MSP430_10, 28) >=20=20 > END_RELOC_NUMBERS (R_MSP430_max) >=20=20 > +/* TODO: Define a set of flags that are appropriate for storage in the e= _flags field. > + * Potential members include: > + * - Whether CPUX instructions are present > + * - Whether hardware multiply register references are present (which ki= nd) > + * - The code addressing mode > + * - The data addressing mode > + */ > + > +/* Pre-uniarch versions of binutils stored machine types in the > + * e_flags field, with values up to 471 decimal. Now we store the > + * machine type in the e_mach field, and use e_flags to identify the > + * characteristics of the code. > + * > + * Use the following flag to indicate that this object file uses the > + * uniarch flag layout. */ > +#define EF_MSP430_UNIARCH 0x10000000 > + > +#define EF_MSP430_ARCH_430 0x00000000 > +#define EF_MSP430_ARCH_430X 0x00000001 > +#define EF_MSP430_ARCH 0x000000FF > +#if 0 > +/* These are symbol-associated, not archive-associated, attributes. > + * Not sure what to do with them. */ > +#define EF_MSP430_CPU_430 0x00000000 > +#define EF_MSP430_CPU_430X 0x00000200 > +#define EF_MSP430_CPU_430XV2 0x00000300 > +#define EF_MSP430_CPU 0x00000300 > +#define EF_MSP430_MPY_NONE 0x00000000 > +#define EF_MSP430_MPY_16 0x00001000 > +#define EF_MSP430_MPY_16_SE (0x00008000 + EF_MSP430_MPY_16) > +#define EF_MSP430_MPY_32 0x00002000 > +#define EF_MSP430_MPY_32_DW (0x00008000 + EF_MSP430_MPY_32) > +#define EF_MSP430_MPY_CLASS 0x00003000 > +#define EF_MSP430_MPY 0x0000F000 > +#define EF_MSP430_CODE_NEAR 0x00010000 > +#define EF_MSP430_CODE_FAR 0x00020000 > +#define EF_MSP430_CODE_MIXED 0x00030000 > +#define EF_MSP430_CODE 0x00030000 > +#define EF_MSP430_DATA_NEAR 0x00040000 > +#define EF_MSP430_DATA_FAR 0x00080000 > +#define EF_MSP430_DATA_MIXED 0x000c0000 > +#define EF_MSP430_DATA 0x000c0000 > +#define EF_MSP430_A20 0x000F0000 > +#endif > + > #endif /* _ELF_MSP430_H */ > diff --git binutils-2.21.1a.orig/include/opcode/msp430.h binutils-2.21.1a= /include/opcode/msp430.h > index d3bf130..b6b1707 100644 > --- binutils-2.21.1a.orig/include/opcode/msp430.h > +++ binutils-2.21.1a/include/opcode/msp430.h > @@ -1,6 +1,6 @@ > /* Opcode table for the TI MSP430 microcontrollers >=20=20 > - Copyright 2002, 2004, 2010 Free Software Foundation, Inc. > + Copyright 2002, 2004, 2010-2012 Free Software Foundation, Inc. > Contributed by Dmitry Diky >=20=20=20=20=20 > This program is free software; you can redistribute it and/or modify > @@ -26,99 +26,289 @@ struct msp430_operand_s > int ol; /* Operand length words. */ > int am; /* Addr mode. */ > int reg; /* Register. */ > - int mode; /* Pperand mode. */ > -#define OP_REG 0 > -#define OP_EXP 1 > #ifndef DASM_SECTION > expressionS exp; > #endif > }; >=20=20 > -#define BYTE_OPERATION (1 << 6) /* Byte operation flag for all instruc= tions. */ > +#define BYTE_OPERATION (1 << 6) /* Byte operation flag for 430= instructions. */ > +#define BYTE_OPERATION_X (1 << 22) /* Byte operation flag for 430= x instructions. */ > +#define NON_ADDR_OPERATION (1 << 6) /* Address operation flag for = 430x instructions. */ > + > +typedef enum=20 > +{=20 > + DEFAULT_OP, /* instruction has no modifier (treat as .w) */ > + WORD_OP, /* .w */ > + BYTE_OP, /* .b */ > + ADDR_OP /* .a */ > +}=20 > +opwidth_t; > + > +/** Bit-markers for type of CPU present. */ > +typedef enum msp430_cpu_e > +{ > + MSP430_CPU_MSP430 =3D 0x0000, > + MSP430_CPU_MSP430X =3D 0x0002, > + MSP430_CPU_MSP430XV2 =3D 0x0003, > + MSP430_CPU =3D 0x0003, > +} msp430_cpu_e; > + > +/** Bit-markers for type of hardware multiplier present. */ > +typedef enum msp430_mpy_e > +{ > + MSP430_MPY_NONE =3D 0x0000, > + MSP430_MPY_16 =3D 0x0010, > + MSP430_MPY_16SE =3D 0x0011, > + MSP430_MPY_32 =3D 0x0020, > + MSP430_MPY_32DW =3D 0x0022, > + MSP430_MPY =3D 0x0030 > +} msp430_mpy_e; > + > +/* Constants for common registers */ > +#define REGNO_MIN 0 > +#define REGNO_MAX 15 > +#define REGNO_PC 0 > +#define REGNO_SP 1 > +#define REGNO_SR 2 > +#define REGNO_CG1 2 > +#define REGNO_CG2 3 > + > +/* Source (2-bit) and destination (1-bit) addressing mode constants. */ > +#define AM_Register 0 > +#define AM_Indexed 1 > +/* Symbolic is indexed off r0=3DPC */ > +#define AM_Symbolic 1 > +/* Absolute is indexed off r2=3DCG1 (0) */ > +#define AM_Absolute 1 > +/* Source-only addressing mode constants */ > +#define AMs_IndirectRegister 2 > +#define AMs_IndirectAutoIncrement 3 > +/* Immediate is indirect auto increment of r0=3DPC */ > +#define AMs_Immediate 3 > + > +/* Mask all but the low 8 bits */ > +#define MASK_8(_x) ((_x) & 0x000000FF) > +/* Mask all but the low 10 bits */ > +#define MASK_10(_x) ((_x) & 0x000003FF) > +/* Mask all but the low 16 bits */ > +#define MASK_16(_x) ((_x) & 0x0000FFFF) > +/* Mask all but the low 20 bits */ > +#define MASK_20(_x) ((_x) & 0x000FFFFF) > +/* Mask all but the low 32 bits */ > +#define MASK_32(_x) ((_x) & 0xFFFFFFFF) > + > +typedef enum > +{ > + FMT_EMULATED =3D 0, > + FMT_DOUBLE_OPERAND, > + FMT_SINGLE_OPERAND, > + FMT_JUMP, > + FMT_X_DOUBLE_OPERAND, > + FMT_X_SINGLE_OPERAND, > + FMT_X_EXCEPTION, > + FMT_X_EMULATED, > + FMT_X_ADDRESS, > + > + FMT_X =3D FMT_X_DOUBLE_OPERAND, > + FMT_MASK =3D 0x000f, > + > + /* allowed modifiers: .b, .w, .a */ > + MOD_NONE =3D 0,=20 > + MOD_W =3D 1 << 4,=20 > + MOD_B =3D 1 << 5,=20 > + MOD_A =3D 1 << 6, > + MOD_MASK =3D 0x0070, > +=20=20 > + /* opcode variant */ > + VAR_MASK =3D 0x0380, > +}=20 > +format_t; > + > +#define OP_V(x) (x << 7) >=20=20 > struct msp430_opcode_s > { > char *name; > - int fmt; > - int insn_opnumb; > - int bin_opcode; > - int bin_mask; > + format_t fmt; > + unsigned int insn_opnumb; > + unsigned int bin_opcode; > + unsigned int bin_mask; > +}; > + > +#define opcode_format(opcode) (opcode->fmt & FMT_MASK) > +#define opcode_modifier(opcode) (opcode->fmt & MOD_MASK) > +#define opcode_variant(opcode) ((opcode->fmt & VAR_MASK) >> 7) > + > +/* opcode variants: */ > +enum > +{=20=20=20 > + V_NONE =3D 0, /* ordinary instruction */ > + > + /* FMT_EMULATED: */ > + V_NOOP, /* no operands: set/clear bit instructions, reti= */ > + V_SHIFT, /* shift instructions */ > + V_BR, /* br instruction */ > +=20=20=20 > + /* FMT_SINGLE_OPERAND: */ > + V_RETI =3D 1, /* reti */ > + V_CALL =3D 2, /* hex operand in disassembly */ > + V_PUSH, /* operand is source, not dest */ > + > + /* FMT_X_SINGLE_OPERAND: */ > + /* V_NONE - #N operand disallowed */ > + V_SWPSXT =3D 1, /* #N operand disallowed, special A/L, B/W bit= s case with .a modifier */ > + V_PUSHX, /* #N operand allowed */ > + > + /* FMT_X_EXCEPTIONS: */ > + V_CALLA =3D 0, /* calla */ > + V_ROTM, /* two operands, rotations */ > + V_POPM, /* two operands, popm */ > + V_PUSHM, /* two operands, pushm */ > + > + /* FMT_X_EMULATED: */ > + /* V_NONE - substituted by 430x double operand i= nstruction */ > + V_X_SHIFT, /* shifts */ > + V_RETA, /* reta, short instruction, no operands */ > + V_EMU_ADDR, /* substituted by address instruction other than= mova */ > + V_BRA, /* bra, substituted by mova address instruction = =3D=3D format II exception instruction */ > + /* clra emulated by msp430 instruction */ > + > + /* FMT_X_ADDRESS: */ > + V_MOVA =3D 1, /* mova, more address modes allowed */ > + V_CG2_TWO, /* r3 has value #2 (instead of #0) */ > }; >=20=20 > -#define MSP_INSN(name, size, numb, bin, mask) { #name, size, numb, bin, = mask } > +/* For validation purposes, we ensure the tests include at least one > + opcode of every distinct pattern. Identify the opcodes with this > + sequence: > +grep MSP_INSN include/opcode/msp430.h \ > + | cut -c20-86 \ > + | sort \ > + | uniq \ > + | while read PATTERN ; do=20 > + fgrep "${PATTERN}" include/opcode/msp430.h \ > + | head -1 > +done > + */=20=20=20 > + > +#define MSP_INSN(name, format, opnumb, bin, mask) { #name, format, opnum= b, bin, mask } >=20=20 > -static struct msp430_opcode_s msp430_opcodes[] =3D=20 > +static struct msp430_opcode_s const msp430_opcodes[] =3D=20 > { > - MSP_INSN (and, 1, 2, 0xf000, 0xf000), > - MSP_INSN (inv, 0, 1, 0xe330, 0xfff0), > - MSP_INSN (xor, 1, 2, 0xe000, 0xf000), > - MSP_INSN (setz, 0, 0, 0xd322, 0xffff), > - MSP_INSN (setc, 0, 0, 0xd312, 0xffff), > - MSP_INSN (eint, 0, 0, 0xd232, 0xffff), > - MSP_INSN (setn, 0, 0, 0xd222, 0xffff), > - MSP_INSN (bis, 1, 2, 0xd000, 0xf000), > - MSP_INSN (clrz, 0, 0, 0xc322, 0xffff), > - MSP_INSN (clrc, 0, 0, 0xc312, 0xffff), > - MSP_INSN (dint, 0, 0, 0xc232, 0xffff), > - MSP_INSN (clrn, 0, 0, 0xc222, 0xffff), > - MSP_INSN (bic, 1, 2, 0xc000, 0xf000), > - MSP_INSN (bit, 1, 2, 0xb000, 0xf000), > - MSP_INSN (dadc, 0, 1, 0xa300, 0xff30), > - MSP_INSN (dadd, 1, 2, 0xa000, 0xf000), > - MSP_INSN (tst, 0, 1, 0x9300, 0xff30), > - MSP_INSN (cmp, 1, 2, 0x9000, 0xf000), > - MSP_INSN (decd, 0, 1, 0x8320, 0xff30), > - MSP_INSN (dec, 0, 1, 0x8310, 0xff30), > - MSP_INSN (sub, 1, 2, 0x8000, 0xf000), > - MSP_INSN (sbc, 0, 1, 0x7300, 0xff30), > - MSP_INSN (subc, 1, 2, 0x7000, 0xf000), > - MSP_INSN (adc, 0, 1, 0x6300, 0xff30), > - MSP_INSN (rlc, 0, 2, 0x6000, 0xf000), > - MSP_INSN (addc, 1, 2, 0x6000, 0xf000), > - MSP_INSN (incd, 0, 1, 0x5320, 0xff30), > - MSP_INSN (inc, 0, 1, 0x5310, 0xff30), > - MSP_INSN (rla, 0, 2, 0x5000, 0xf000), > - MSP_INSN (add, 1, 2, 0x5000, 0xf000), > - MSP_INSN (nop, 0, 0, 0x4303, 0xffff), > - MSP_INSN (clr, 0, 1, 0x4300, 0xff30), > - MSP_INSN (ret, 0, 0, 0x4130, 0xff30), > - MSP_INSN (pop, 0, 1, 0x4130, 0xff30), > - MSP_INSN (br, 0, 3, 0x4000, 0xf000), > - MSP_INSN (mov, 1, 2, 0x4000, 0xf000), > - MSP_INSN (jmp, 3, 1, 0x3c00, 0xfc00), > - MSP_INSN (jl, 3, 1, 0x3800, 0xfc00), > - MSP_INSN (jge, 3, 1, 0x3400, 0xfc00), > - MSP_INSN (jn, 3, 1, 0x3000, 0xfc00), > - MSP_INSN (jc, 3, 1, 0x2c00, 0xfc00), > - MSP_INSN (jhs, 3, 1, 0x2c00, 0xfc00), > - MSP_INSN (jnc, 3, 1, 0x2800, 0xfc00), > - MSP_INSN (jlo, 3, 1, 0x2800, 0xfc00), > - MSP_INSN (jz, 3, 1, 0x2400, 0xfc00), > - MSP_INSN (jeq, 3, 1, 0x2400, 0xfc00), > - MSP_INSN (jnz, 3, 1, 0x2000, 0xfc00), > - MSP_INSN (jne, 3, 1, 0x2000, 0xfc00), > - MSP_INSN (reti, 2, 0, 0x1300, 0xffc0), > - MSP_INSN (call, 2, 1, 0x1280, 0xffc0), > - MSP_INSN (push, 2, 1, 0x1200, 0xff80), > - MSP_INSN (sxt, 2, 1, 0x1180, 0xffc0), > - MSP_INSN (rra, 2, 1, 0x1100, 0xff80), > - MSP_INSN (swpb, 2, 1, 0x1080, 0xffc0), > - MSP_INSN (rrc, 2, 1, 0x1000, 0xff80), > - /* Simple polymorphs. */ > - MSP_INSN (beq, 4, 0, 0, 0xffff), > - MSP_INSN (bne, 4, 1, 0, 0xffff), > - MSP_INSN (blt, 4, 2, 0, 0xffff), > - MSP_INSN (bltu, 4, 3, 0, 0xffff), > - MSP_INSN (bge, 4, 4, 0, 0xffff), > - MSP_INSN (bgeu, 4, 5, 0, 0xffff), > - MSP_INSN (bltn, 4, 6, 0, 0xffff), > - MSP_INSN (jump, 4, 7, 0, 0xffff), > - /* Long polymorphs. */ > - MSP_INSN (bgt, 5, 0, 0, 0xffff), > - MSP_INSN (bgtu, 5, 1, 0, 0xffff), > - MSP_INSN (bleu, 5, 2, 0, 0xffff), > - MSP_INSN (ble, 5, 3, 0, 0xffff), > + MSP_INSN (and, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0xf000, 0xfffff000), > + MSP_INSN (inv, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0xe330, 0xfffffff0), > + MSP_INSN (xor, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0xe000, 0xfffff000), > + MSP_INSN (setz, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xd322, 0xffffffff), > + MSP_INSN (setc, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xd312, 0xffffffff), > + MSP_INSN (eint, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xd232, 0xffffffff), > + MSP_INSN (setn, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xd222, 0xffffffff), > + MSP_INSN (bis, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0xd000, 0xfffff000), > + MSP_INSN (clrz, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xc322, 0xffffffff), > + MSP_INSN (clrc, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xc312, 0xffffffff), > + MSP_INSN (dint, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xc232, 0xffffffff), > + MSP_INSN (clrn, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0xc222, 0xffffffff), > + MSP_INSN (bic, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0xc000, 0xfffff000), > + MSP_INSN (bit, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0xb000, 0xfffff000), > + MSP_INSN (dadc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0xa300, 0xffffff30), > + MSP_INSN (dadd, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0xa000, 0xfffff000), > + MSP_INSN (tst, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x9300, 0xffffff30), > + MSP_INSN (cmp, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0x9000, 0xfffff000), > + MSP_INSN (decd, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x8320, 0xffffff30), > + MSP_INSN (dec, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x8310, 0xffffff30), > + MSP_INSN (sub, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0x8000, 0xfffff000), > + MSP_INSN (sbc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x7300, 0xffffff30), > + MSP_INSN (subc, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0x7000, 0xfffff000), > + MSP_INSN (adc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x6300, 0xffffff30), > + MSP_INSN (rlc, FMT_EMULATED | MOD_W|MOD_B | OP_V(V_SH= IFT), 2, 0x6000, 0xfffff000), > + MSP_INSN (addc, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0x6000, 0xfffff000), > + MSP_INSN (incd, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x5320, 0xffffff30), > + MSP_INSN (inc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x5310, 0xffffff30), > + MSP_INSN (rla, FMT_EMULATED | MOD_W|MOD_B | OP_V(V_SH= IFT), 2, 0x5000, 0xfffff000), > + MSP_INSN (add, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0x5000, 0xfffff000), > + MSP_INSN (nop, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0x4303, 0xffffffff), > + MSP_INSN (clr, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x4300, 0xffffff30), > + MSP_INSN (ret, FMT_EMULATED | MOD_NONE | OP_V(V_NO= OP), 0, 0x4130, 0xffffffff), > + MSP_INSN (pop, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), = 1, 0x4130, 0xffffff30), > + MSP_INSN (br, FMT_EMULATED | MOD_NONE | OP_V(V_BR= ), 1, 0x4000, 0xfffff08f), > + MSP_INSN (mov, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 2, 0x4000, 0xfffff000), > + > + MSP_INSN (jmp, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x3c00, 0xfffffc00), > + MSP_INSN (jl, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x3800, 0xfffffc00), > + MSP_INSN (jge, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x3400, 0xfffffc00), > + MSP_INSN (jn, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x3000, 0xfffffc00), > + MSP_INSN (jc, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2c00, 0xfffffc00), > + MSP_INSN (jhs, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2c00, 0xfffffc00), > + MSP_INSN (jnc, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2800, 0xfffffc00), > + MSP_INSN (jlo, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2800, 0xfffffc00), > + MSP_INSN (jz, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2400, 0xfffffc00), > + MSP_INSN (jeq, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2400, 0xfffffc00), > + MSP_INSN (jnz, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2000, 0xfffffc00), > + MSP_INSN (jne, FMT_JUMP | MOD_NONE | OP_V(0), = 1, 0x2000, 0xfffffc00), > + > + MSP_INSN (reti, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(V_RE= TI), 0, 0x1300, 0xffffffc0), > + MSP_INSN (call, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(V_CA= LL), 1, 0x1280, 0xffffffc0), > + MSP_INSN (push, FMT_SINGLE_OPERAND | MOD_W|MOD_B | OP_V(V_PU= SH), 1, 0x1200, 0xffffff80), > + MSP_INSN (sxt, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(0), = 1, 0x1180, 0xffffffc0), > + MSP_INSN (rra, FMT_SINGLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 1, 0x1100, 0xffffff80), > + MSP_INSN (swpb, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(0), = 1, 0x1080, 0xffffffc0), > + MSP_INSN (rrc, FMT_SINGLE_OPERAND | MOD_W|MOD_B | OP_V(0), = 1, 0x1000, 0xffffff80), > + > + > + /* emulated instructions placed just before instruction emulated by fo= r disassembly search */ > + MSP_INSN (popx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x41301800, 0xff30f800), /* MOVX @SP+, dst */ > + MSP_INSN (clrx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x43001800, 0xff30f800), /* MOVX #0, dst */ > + MSP_INSN (movx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0x40001800, 0xf000f800), > + MSP_INSN (incx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x53101800, 0xff30f800), /* ADDX #1, dst */ > + MSP_INSN (incdx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x53201800, 0xff30f800), /* ADDX #2, dst */ > + MSP_INSN (rlax, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(V_X_= SHIFT), 1, 0x50001800, 0xf000f800), /* ADDX dst, dst */ > + MSP_INSN (addx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0x50001800, 0xf000f800), > + MSP_INSN (adcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x63001800, 0xff30f800), /* ADDCX #0, dst */ > + MSP_INSN (rlcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(V_X_= SHIFT), 1, 0x60001800, 0xf000f800), /* ADDCX dst, dst */ > + MSP_INSN (addcx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0x60001800, 0xf000f800), > + MSP_INSN (sbcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x73001800, 0xff30f800), /* SUBCX #0, dst */ > + MSP_INSN (subcx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0x70001800, 0xf000f800), > + MSP_INSN (decx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x83101800, 0xff30f800), /* SUBX #1, dst */ > + MSP_INSN (decdx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x83201800, 0xff30f800), /* SUBX #2, dst */ > + MSP_INSN (subx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0x80001800, 0xf000f800), > + MSP_INSN (tstx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x93001800, 0xff30f800), /* CMPX #0, dst */ > + MSP_INSN (cmpx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0x90001800, 0xf000f800), > + MSP_INSN (dadcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0xa3001800, 0xff30f800), /* DADDX #0, dst */ > + MSP_INSN (daddx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0xa0001800, 0xf000f800), > + MSP_INSN (bitx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0xb0001800, 0xf000f800), > + MSP_INSN (bicx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0xc0001800, 0xf000f800), > + MSP_INSN (bisx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0xd0001800, 0xf000f800), > + MSP_INSN (invx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0xe3301800, 0xff30f800), /* XORX #-1, dst */ > + MSP_INSN (xorx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0xe0001800, 0xf000f800), > + MSP_INSN (andx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 2, 0xf0001800, 0xf000f800), > +=20=20 > + MSP_INSN (rrcx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x10001800, 0xff80f900), > + MSP_INSN (rrux, FMT_X_SINGLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x10001900, 0xff80f900), > + MSP_INSN (swpbx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_A | OP_V(V_SW= PSXT), 1, 0x10801800, 0xffc0f800), > + MSP_INSN (rrax, FMT_X_SINGLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), = 1, 0x11001800, 0xff80f800), > + MSP_INSN (sxtx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_A | OP_V(V_SW= PSXT), 1, 0x11801800, 0xffc0f800), > + MSP_INSN (pushx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(V_PU= SHX), 1, 0x12001800, 0xff80f800), > + > + MSP_INSN (calla, FMT_X_EXCEPTION | MOD_NONE | OP_V(V_CA= LLA), 1, 0x1300, 0xffffff00), > + MSP_INSN (pushm, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_PU= SHM), 2, 0x1400, 0xfffffe00), > + MSP_INSN (popm, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_PO= PM), 2, 0x1600, 0xfffffe00), > + MSP_INSN (rrcm, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_RO= TM), 2, 0x0040, 0xfffff3e0), > + MSP_INSN (rram, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_RO= TM), 2, 0x0140, 0xfffff3e0), > + MSP_INSN (rlam, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_RO= TM), 2, 0x0240, 0xfffff3e0), > + MSP_INSN (rrum, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_RO= TM), 2, 0x0340, 0xfffff3e0), >=20=20 > + /* Address. */ > + MSP_INSN (incda, FMT_X_EMULATED | MOD_NONE | OP_V(V_EM= U_ADDR), 1, 0x03e0, 0xfffffff0), /* ADDA #2, Rdst =3D ADDA R3, R= dst */ > + MSP_INSN (adda, FMT_X_ADDRESS | MOD_NONE | OP_V(V_CG= 2_TWO), 2, 0x00a0, 0xfffff0b0), > + MSP_INSN (tsta, FMT_X_EMULATED | MOD_NONE | OP_V(V_EM= U_ADDR), 1, 0x03d0, 0xfffffff0), /* CMPA #0, Rdst =3D CMPA R3, R= dst */ > + MSP_INSN (cmpa, FMT_X_ADDRESS | MOD_NONE | OP_V(0), = 2, 0x0090, 0xfffff0b0), > + MSP_INSN (decda, FMT_X_EMULATED | MOD_NONE | OP_V(V_EM= U_ADDR), 1, 0x03f0, 0xfffffff0), /* SUBA #2, Rdst =3D SUBA R3, R= dst */ > + MSP_INSN (suba, FMT_X_ADDRESS | MOD_NONE | OP_V(V_CG= 2_TWO), 2, 0x00b0, 0xfffff0b0), > + MSP_INSN (reta, FMT_X_EMULATED | MOD_NONE | OP_V(V_RE= TA), 0, 0x0110, 0xffffffff), /* MOVA @SP+, PC */ > + MSP_INSN (bra, FMT_X_EMULATED | MOD_NONE | OP_V(V_BR= A), 1, 0x0000, 0xfffff0cf), /* MOVA dst, PC */ > + MSP_INSN (bra, FMT_X_EMULATED | MOD_NONE | OP_V(V_BR= A), 1, 0x0080, 0xfffff0bf), /* MOVA #imm20, PC; MOVA Rsrc, = Rdst */ > + MSP_INSN (clra, FMT_X_EMULATED | MOD_NONE | OP_V(V_MO= VA), 1, 0x03c0, 0xfffffff0), /* MOVA #0, Rdst */ > + MSP_INSN (mova, FMT_X_ADDRESS | MOD_NONE | OP_V(V_MO= VA), 1, 0x0000, 0xfffff000), > +=20=20 > /* End of instruction set. */ > { NULL, 0, 0, 0, 0 } > }; > diff --git binutils-2.21.1a.orig/ld/Makefile.am binutils-2.21.1a/ld/Makef= ile.am > index 1280b64..9a290d8 100644 > --- binutils-2.21.1a.orig/ld/Makefile.am > +++ binutils-2.21.1a/ld/Makefile.am > @@ -317,65 +317,7 @@ ALL_EMULATION_SOURCES =3D \ > emipspe.c \ > emn10200.c \ > emn10300.c \ > - emsp430x110.c \ > - emsp430x1101.c \ > - emsp430x1111.c \ > - emsp430x112.c \ > - emsp430x1121.c \ > - emsp430x1122.c \ > - emsp430x1132.c \ > - emsp430x122.c \ > - emsp430x1222.c \ > - emsp430x123.c \ > - emsp430x1232.c \ > - emsp430x133.c \ > - emsp430x1331.c \ > - emsp430x135.c \ > - emsp430x1351.c \ > - emsp430x147.c \ > - emsp430x148.c \ > - emsp430x149.c \ > - emsp430x155.c \ > - emsp430x156.c \ > - emsp430x157.c \ > - emsp430x1610.c \ > - emsp430x1611.c \ > - emsp430x1612.c \ > - emsp430x167.c \ > - emsp430x168.c \ > - emsp430x169.c \ > - emsp430x2101.c \ > - emsp430x2111.c \ > - emsp430x2121.c \ > - emsp430x2131.c \ > - emsp430x311.c \ > - emsp430x312.c \ > - emsp430x313.c \ > - emsp430x314.c \ > - emsp430x315.c \ > - emsp430x323.c \ > - emsp430x325.c \ > - emsp430x336.c \ > - emsp430x337.c \ > - emsp430x412.c \ > - emsp430x413.c \ > - emsp430x415.c \ > - emsp430x417.c \ > - emsp430x435.c \ > - emsp430x436.c \ > - emsp430x437.c \ > - emsp430x447.c \ > - emsp430x448.c \ > - emsp430x449.c \ > - emsp430xE423.c \ > - emsp430xE425.c \ > - emsp430xE427.c \ > - emsp430xG437.c \ > - emsp430xG438.c \ > - emsp430xG439.c \ > - emsp430xW423.c \ > - emsp430xW425.c \ > - emsp430xW427.c \ > + emsp430.c \ > enews.c \ > ens32knbsd.c \ > eor32.c \ > @@ -1335,242 +1277,10 @@ emn10300.c: $(srcdir)/emulparams/mn10300.sh \ > $(srcdir)/emulparams/mn10200.sh \ > $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} > ${GENSCRIPTS} mn10300 "$(tdir_mn10300)" > -emsp430x110.c: $(srcdir)/emulparams/msp430all.sh \ > +emsp430.c: $(srcdir)/emulparams/msp430uni.sh \ > $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x110 "$(tdir_msp430x110)" msp430all > -emsp430x1101.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1101 "$(tdir_msp430x1101)" msp430all > -emsp430x1111.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1111 "$(tdir_msp430x1111)" msp430all > -emsp430x112.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x112 "$(tdir_msp430x112)" msp430all > -emsp430x1121.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1121 "$(tdir_msp430x1121)" msp430all > -emsp430x1122.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1122 "$(tdir_msp430x1122)" msp430all > -emsp430x1132.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1132 "$(tdir_msp430x1132)" msp430all > -emsp430x122.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x122 "$(tdir_msp430x122)" msp430all > -emsp430x1222.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1222 "$(tdir_msp430x1222)" msp430all > -emsp430x123.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x123 "$(tdir_msp430x123)" msp430all > -emsp430x1232.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1232 "$(tdir_msp430x1232)" msp430all > -emsp430x133.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x133 "$(tdir_msp430x133)" msp430all > -emsp430x1331.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1331 "$(tdir_msp430x1331)" msp430all > -emsp430x135.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x135 "$(tdir_msp430x135)" msp430all > -emsp430x1351.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1351 "$(tdir_msp430x1351)" msp430all > -emsp430x147.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x147 "$(tdir_msp430x147)" msp430all > -emsp430x148.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x148 "$(tdir_msp430x148)" msp430all > -emsp430x149.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x149 "$(tdir_msp430x149)" msp430all > -emsp430x155.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x155 "$(tdir_msp430x155)" msp430all > -emsp430x156.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x156 "$(tdir_msp430x156)" msp430all > -emsp430x157.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x157 "$(tdir_msp430x157)" msp430all > -emsp430x1610.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1610 "$(tdir_msp430x1610)" msp430all > -emsp430x1611.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1611 "$(tdir_msp430x1611)" msp430all > -emsp430x1612.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1612 "$(tdir_msp430x1612)" msp430all > -emsp430x167.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x167 "$(tdir_msp430x167)" msp430all > -emsp430x168.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x168 "$(tdir_msp430x168)" msp430all > -emsp430x169.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x169 "$(tdir_msp430x169)" msp430all > -emsp430x2101.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2101 "$(tdir_msp430x2101)" msp430all > -emsp430x2111.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2111 "$(tdir_msp430x2111)" msp430all > -emsp430x2121.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2121 "$(tdir_msp430x2121)" msp430all > -emsp430x2131.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2131 "$(tdir_msp430x2131)" msp430all > -emsp430x311.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x311 "$(tdir_msp430x311)" msp430all > -emsp430x312.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x312 "$(tdir_msp430x312)" msp430all > -emsp430x313.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x313 "$(tdir_msp430x313)" msp430all > -emsp430x314.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x314 "$(tdir_msp430x314)" msp430all > -emsp430x315.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x315 "$(tdir_msp430x315)" msp430all > -emsp430x323.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x323 "$(tdir_msp430x323)" msp430all > -emsp430x325.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x325 "$(tdir_msp430x325)" msp430all > -emsp430x336.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x336 "$(tdir_msp430x336)" msp430all > -emsp430x337.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x337 "$(tdir_msp430x337)" msp430all > -emsp430x412.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x412 "$(tdir_msp430x412)" msp430all > -emsp430x413.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x413 "$(tdir_msp430x413)" msp430all > -emsp430x415.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x415 "$(tdir_msp430x415)" msp430all > -emsp430x417.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x417 "$(tdir_msp430x417)" msp430all > -emsp430x435.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x435 "$(tdir_msp430x435)" msp430all > -emsp430x436.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x436 "$(tdir_msp430x436)" msp430all > -emsp430x437.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x437 "$(tdir_msp430x437)" msp430all > -emsp430x447.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x447 "$(tdir_msp430x447)" msp430all > -emsp430x448.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x448 "$(tdir_msp430x448)" msp430all > -emsp430x449.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x449 "$(tdir_msp430x449)" msp430all > -emsp430xE423.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xE423 "$(tdir_msp430xE423)" msp430all > -emsp430xE425.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xE425 "$(tdir_msp430xE425)" msp430all > -emsp430xE427.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xE427 "$(tdir_msp430xE427)" msp430all > -emsp430xG437.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xG437 "$(tdir_msp430xG437)" msp430all > -emsp430xG438.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xG438 "$(tdir_msp430xG438)" msp430all > -emsp430xG439.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xG439 "$(tdir_msp430xG439)" msp430all > -emsp430xW423.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xW423 "$(tdir_msp430xW423)" msp430all > -emsp430xW425.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xW425 "$(tdir_msp430xW425)" msp430all > -emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all > + ${GENSCRIPTS} msp430 "$(tdir_msp430)" msp430uni > enews.c: $(srcdir)/emulparams/news.sh \ > $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEP= ENDS} > ${GENSCRIPTS} news "$(tdir_news)" > diff --git binutils-2.21.1a.orig/ld/Makefile.in binutils-2.21.1a/ld/Makef= ile.in > index 00fcd72..5e1dbc0 100644 > --- binutils-2.21.1a.orig/ld/Makefile.in > +++ binutils-2.21.1a/ld/Makefile.in > @@ -622,65 +622,7 @@ ALL_EMULATION_SOURCES =3D \ > emipspe.c \ > emn10200.c \ > emn10300.c \ > - emsp430x110.c \ > - emsp430x1101.c \ > - emsp430x1111.c \ > - emsp430x112.c \ > - emsp430x1121.c \ > - emsp430x1122.c \ > - emsp430x1132.c \ > - emsp430x122.c \ > - emsp430x1222.c \ > - emsp430x123.c \ > - emsp430x1232.c \ > - emsp430x133.c \ > - emsp430x1331.c \ > - emsp430x135.c \ > - emsp430x1351.c \ > - emsp430x147.c \ > - emsp430x148.c \ > - emsp430x149.c \ > - emsp430x155.c \ > - emsp430x156.c \ > - emsp430x157.c \ > - emsp430x1610.c \ > - emsp430x1611.c \ > - emsp430x1612.c \ > - emsp430x167.c \ > - emsp430x168.c \ > - emsp430x169.c \ > - emsp430x2101.c \ > - emsp430x2111.c \ > - emsp430x2121.c \ > - emsp430x2131.c \ > - emsp430x311.c \ > - emsp430x312.c \ > - emsp430x313.c \ > - emsp430x314.c \ > - emsp430x315.c \ > - emsp430x323.c \ > - emsp430x325.c \ > - emsp430x336.c \ > - emsp430x337.c \ > - emsp430x412.c \ > - emsp430x413.c \ > - emsp430x415.c \ > - emsp430x417.c \ > - emsp430x435.c \ > - emsp430x436.c \ > - emsp430x437.c \ > - emsp430x447.c \ > - emsp430x448.c \ > - emsp430x449.c \ > - emsp430xE423.c \ > - emsp430xE425.c \ > - emsp430xE427.c \ > - emsp430xG437.c \ > - emsp430xG438.c \ > - emsp430xG439.c \ > - emsp430xW423.c \ > - emsp430xW425.c \ > - emsp430xW427.c \ > + emsp430.c \ > enews.c \ > ens32knbsd.c \ > eor32.c \ > @@ -1228,65 +1170,7 @@ distclean-compile: > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x110.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1101.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1111.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x112.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1121.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1122.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1132.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x122.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1222.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x123.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1232.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x133.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1331.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x135.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1351.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x147.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x148.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x149.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x155.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x156.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x157.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1610.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1611.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1612.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x167.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x168.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x169.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2101.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2111.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2121.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2131.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x311.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x312.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x313.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x314.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x315.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x323.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x325.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x336.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x337.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x412.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x413.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x415.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x417.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x435.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x436.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x437.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x447.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x448.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x449.Po@am__quot= e@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xE423.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xE425.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xE427.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xG437.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xG438.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xG439.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xW423.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xW425.Po@am__quo= te@ > -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xW427.Po@am__quo= te@ > +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enews.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ens32knbsd.Po@am__quote@ > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eor32.Po@am__quote@ > @@ -2770,242 +2654,10 @@ emn10300.c: $(srcdir)/emulparams/mn10300.sh \ > $(srcdir)/emulparams/mn10200.sh \ > $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} > ${GENSCRIPTS} mn10300 "$(tdir_mn10300)" > -emsp430x110.c: $(srcdir)/emulparams/msp430all.sh \ > +emsp430.c: $(srcdir)/emulparams/msp430uni.sh \ > $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x110 "$(tdir_msp430x110)" msp430all > -emsp430x1101.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1101 "$(tdir_msp430x1101)" msp430all > -emsp430x1111.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1111 "$(tdir_msp430x1111)" msp430all > -emsp430x112.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x112 "$(tdir_msp430x112)" msp430all > -emsp430x1121.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1121 "$(tdir_msp430x1121)" msp430all > -emsp430x1122.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1122 "$(tdir_msp430x1122)" msp430all > -emsp430x1132.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1132 "$(tdir_msp430x1132)" msp430all > -emsp430x122.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x122 "$(tdir_msp430x122)" msp430all > -emsp430x1222.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1222 "$(tdir_msp430x1222)" msp430all > -emsp430x123.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x123 "$(tdir_msp430x123)" msp430all > -emsp430x1232.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1232 "$(tdir_msp430x1232)" msp430all > -emsp430x133.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x133 "$(tdir_msp430x133)" msp430all > -emsp430x1331.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1331 "$(tdir_msp430x1331)" msp430all > -emsp430x135.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x135 "$(tdir_msp430x135)" msp430all > -emsp430x1351.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1351 "$(tdir_msp430x1351)" msp430all > -emsp430x147.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x147 "$(tdir_msp430x147)" msp430all > -emsp430x148.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x148 "$(tdir_msp430x148)" msp430all > -emsp430x149.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x149 "$(tdir_msp430x149)" msp430all > -emsp430x155.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x155 "$(tdir_msp430x155)" msp430all > -emsp430x156.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x156 "$(tdir_msp430x156)" msp430all > -emsp430x157.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x157 "$(tdir_msp430x157)" msp430all > -emsp430x1610.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1610 "$(tdir_msp430x1610)" msp430all > -emsp430x1611.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1611 "$(tdir_msp430x1611)" msp430all > -emsp430x1612.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x1612 "$(tdir_msp430x1612)" msp430all > -emsp430x167.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x167 "$(tdir_msp430x167)" msp430all > -emsp430x168.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x168 "$(tdir_msp430x168)" msp430all > -emsp430x169.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x169 "$(tdir_msp430x169)" msp430all > -emsp430x2101.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2101 "$(tdir_msp430x2101)" msp430all > -emsp430x2111.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2111 "$(tdir_msp430x2111)" msp430all > -emsp430x2121.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2121 "$(tdir_msp430x2121)" msp430all > -emsp430x2131.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x2131 "$(tdir_msp430x2131)" msp430all > -emsp430x311.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x311 "$(tdir_msp430x311)" msp430all > -emsp430x312.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x312 "$(tdir_msp430x312)" msp430all > -emsp430x313.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x313 "$(tdir_msp430x313)" msp430all > -emsp430x314.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x314 "$(tdir_msp430x314)" msp430all > -emsp430x315.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x315 "$(tdir_msp430x315)" msp430all > -emsp430x323.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x323 "$(tdir_msp430x323)" msp430all > -emsp430x325.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x325 "$(tdir_msp430x325)" msp430all > -emsp430x336.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x336 "$(tdir_msp430x336)" msp430all > -emsp430x337.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x337 "$(tdir_msp430x337)" msp430all > -emsp430x412.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x412 "$(tdir_msp430x412)" msp430all > -emsp430x413.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x413 "$(tdir_msp430x413)" msp430all > -emsp430x415.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x415 "$(tdir_msp430x415)" msp430all > -emsp430x417.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x417 "$(tdir_msp430x417)" msp430all > -emsp430x435.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x435 "$(tdir_msp430x435)" msp430all > -emsp430x436.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x436 "$(tdir_msp430x436)" msp430all > -emsp430x437.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x437 "$(tdir_msp430x437)" msp430all > -emsp430x447.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x447 "$(tdir_msp430x447)" msp430all > -emsp430x448.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x448 "$(tdir_msp430x448)" msp430all > -emsp430x449.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430x449 "$(tdir_msp430x449)" msp430all > -emsp430xE423.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xE423 "$(tdir_msp430xE423)" msp430all > -emsp430xE425.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xE425 "$(tdir_msp430xE425)" msp430all > -emsp430xE427.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xE427 "$(tdir_msp430xE427)" msp430all > -emsp430xG437.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xG437 "$(tdir_msp430xG437)" msp430all > -emsp430xG438.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xG438 "$(tdir_msp430xG438)" msp430all > -emsp430xG439.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xG439 "$(tdir_msp430xG439)" msp430all > -emsp430xW423.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xW423 "$(tdir_msp430xW423)" msp430all > -emsp430xW425.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xW425 "$(tdir_msp430xW425)" msp430all > -emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \ > - $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \ > - ${GEN_DEPENDS} > - ${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all > + ${GENSCRIPTS} msp430 "$(tdir_msp430)" msp430uni > enews.c: $(srcdir)/emulparams/news.sh \ > $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEP= ENDS} > ${GENSCRIPTS} news "$(tdir_news)" > diff --git binutils-2.21.1a.orig/ld/configure.tgt binutils-2.21.1a/ld/con= figure.tgt > index 90d7461..b9a0624 100644 > --- binutils-2.21.1a.orig/ld/configure.tgt > +++ binutils-2.21.1a/ld/configure.tgt > @@ -429,8 +429,7 @@ mn10300-*-*) targ_emul=3Dmn10300 > ;; > mt-*elf) targ_emul=3Delf32mt > ;; > -msp430-*-*) targ_emul=3Dmsp430x110 > - targ_extra_emuls=3D"msp430x112 msp430x1101 msp43= 0x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x122= 2 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp4= 30x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 ms= p430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430= x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 ms= p430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 = msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp4= 30xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x43= 7 msp430x447 msp430x448 msp430x449" > +msp430-*-*) targ_emul=3Dmsp430 > ;; > ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=3Dpc532macha ;; > ns32k-*-netbsd* | ns32k-pc532-lites*) targ_emul=3Dns32knbsd > diff --git binutils-2.21.1a.orig/ld/emulparams/msp430all.sh binutils-2.21= .1a/ld/emulparams/msp430all.sh > deleted file mode 100644 > index 57d21c2..0000000 > --- binutils-2.21.1a.orig/ld/emulparams/msp430all.sh > +++ /dev/null > @@ -1,553 +0,0 @@ > -#!/bin/sh > - > -# This called by genscripts_extra.sh > - > -MSP430_NAME=3D${EMULATION_NAME} > - > -SCRIPT_NAME=3Delf32msp430 > -TEMPLATE_NAME=3Dgeneric > -EXTRA_EM_FILE=3Dgenelf > -OUTPUT_FORMAT=3D"elf32-msp430" > -MACHINE=3D > -MAXPAGESIZE=3D1 > -EMBEDDED=3Dyes > - > -if [ "${MSP430_NAME}" =3D "msp430x110" ] ; then > -ARCH=3Dmsp:11 > -ROM_START=3D0xfc00 > -ROM_SIZE=3D0x3e0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D128 > -STACK=3D0x280 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1101" ] ; then > -ARCH=3Dmsp:110 > -ROM_START=3D0xfc00 > -ROM_SIZE=3D0x3e0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D128 > -STACK=3D0x280 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1111" ] ; then > -ARCH=3Dmsp:110 > -ROM_START=3D0xf800 > -ROM_SIZE=3D0x07e0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D128 > -STACK=3D0x280 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x112" ] ; then > -ARCH=3Dmsp:11 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0xfe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1121" ] ; then > -ARCH=3Dmsp:110 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0x0fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1122" ] ; then > -ARCH=3Dmsp:110 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0x0fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1132" ] ; then > -ARCH=3Dmsp:110 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x122" ] ; then > -ARCH=3Dmsp:12 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0xfe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1222" ] ; then > -ARCH=3Dmsp:12 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0xfe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x123" ] ; then > -ARCH=3Dmsp:12 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1232" ] ; then > -ARCH=3Dmsp:12 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x133" ] ; then > -ARCH=3Dmsp:13 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1331" ] ; then > -ARCH=3Dmsp:13 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x135" ] ; then > -ARCH=3Dmsp:13 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1351" ] ; then > -ARCH=3Dmsp:13 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x147" ] ; then > -ARCH=3Dmsp:14 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1K > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x148" ] ; then > -ARCH=3Dmsp:14 > -ROM_START=3D0x4000 > -ROM_SIZE=3D0xbfe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x149" ] ; then > -ARCH=3Dmsp:14 > -ROM_START=3D0x1100 > -ROM_SIZE=3D0xeee0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x155" ] ; then > -ARCH=3Dmsp:15 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x156" ] ; then > -ARCH=3Dmsp:15 > -ROM_START=3D0xa000 > -ROM_SIZE=3D0x5fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x157" ] ; then > -ARCH=3Dmsp:15 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1K > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x167" ] ; then > -ARCH=3Dmsp:16 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1K > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x168" ] ; then > -ARCH=3Dmsp:16 > -ROM_START=3D0x4000 > -ROM_SIZE=3D0xbfe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x169" ] ; then > -ARCH=3Dmsp:16 > -ROM_START=3D0x1100 > -ROM_SIZE=3D0xeee0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1610" ] ; then > -ARCH=3Dmsp:16 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x1100 > -RAM_SIZE=3D0x1400 > -STACK=3D0x2500 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1611" ] ; then > -ARCH=3Dmsp:16 > -ROM_START=3D0x4000 > -ROM_SIZE=3D0xbfe0 > -RAM_START=3D0x1100 > -RAM_SIZE=3D0x2800 > -STACK=3D0x3900 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x1612" ] ; then > -ARCH=3Dmsp:16 > -ROM_START=3D0x2500 > -ROM_SIZE=3D0xdae0 > -RAM_START=3D0x1100 > -RAM_SIZE=3D0x1400 > -STACK=3D0x2500 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x2101" ] ; then > -ARCH=3Dmsp:21 > -ROM_START=3D0xFC00 > -ROM_SIZE=3D0x03e0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D128 > -STACK=3D0x280 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x2111" ] ; then > -ARCH=3Dmsp:21 > -ROM_START=3D0xF800 > -ROM_SIZE=3D0x07e0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D128 > -STACK=3D0x280 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x2121" ] ; then > -ARCH=3Dmsp:21 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0x0fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x2131" ] ; then > -ARCH=3Dmsp:21 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x311" ] ; then > -ARCH=3Dmsp:31 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xf800 > -ROM_SIZE=3D0x07e0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D128 > -STACK=3D0x280 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x312" ] ; then > -ARCH=3Dmsp:31 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0x0fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x313" ] ; then > -ARCH=3Dmsp:31 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x314" ] ; then > -ARCH=3Dmsp:31 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xd000 > -ROM_SIZE=3D0x2fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x315" ] ; then > -ARCH=3Dmsp:31 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x323" ] ; then > -ARCH=3Dmsp:32 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x325" ] ; then > -ARCH=3Dmsp:32 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x336" ] ; then > -ARCH=3Dmsp:33 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0xa000 > -ROM_SIZE=3D0x5fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x337" ] ; then > -ARCH=3Dmsp:33 > -SCRIPT_NAME=3Delf32msp430_3 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x412" ] ; then > -ARCH=3Dmsp:41 > -ROM_START=3D0xf000 > -ROM_SIZE=3D0x0fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x413" ] ; then > -ARCH=3Dmsp:41 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x415" ] ; then > -ARCH=3Dmsp:41 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x417" ] ; then > -ARCH=3Dmsp:41 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x435" ] ; then > -ARCH=3Dmsp:43 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x436" ] ; then > -ARCH=3Dmsp:43 > -ROM_START=3D0xa000 > -ROM_SIZE=3D0x5fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x437" ] ; then > -ARCH=3Dmsp:43 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x447" ] ; then > -ARCH=3Dmsp:44 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x448" ] ; then > -ARCH=3Dmsp:44 > -ROM_START=3D0x4000 > -ROM_SIZE=3D0xbfe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430x449" ] ; then > -ARCH=3Dmsp:44 > -ROM_START=3D0x1100 > -ROM_SIZE=3D0xeee0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xE423" ] ; then > -ARCH=3Dmsp:42 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xE425" ] ; then > -ARCH=3Dmsp:42 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xE427" ] ; then > -ARCH=3Dmsp:42 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xG437" ] ; then > -ARCH=3Dmsp:43 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D1024 > -STACK=3D0x600 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xG438" ] ; then > -ARCH=3Dmsp:43 > -ROM_START=3D0x4000 > -ROM_SIZE=3D0xbef0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xG439" ] ; then > -ARCH=3Dmsp:43 > -ROM_START=3D0x1100 > -ROM_SIZE=3D0xeee0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x0800 > -STACK=3D0xa00 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xW423" ] ; then > -ARCH=3Dmsp:42 > -ROM_START=3D0xe000 > -ROM_SIZE=3D0x1fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D256 > -STACK=3D0x300 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xW425" ] ; then > -ARCH=3Dmsp:42 > -ROM_START=3D0xc000 > -ROM_SIZE=3D0x3fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D512 > -STACK=3D0x400 > -fi > - > -if [ "${MSP430_NAME}" =3D "msp430xW427" ] ; then > -ARCH=3Dmsp:42 > -ROM_START=3D0x8000 > -ROM_SIZE=3D0x7fe0 > -RAM_START=3D0x0200 > -RAM_SIZE=3D0x400 > -STACK=3D0x600 > -fi > diff --git binutils-2.21.1a.orig/ld/emulparams/msp430uni.sh binutils-2.21= .1a/ld/emulparams/msp430uni.sh > new file mode 100644 > index 0000000..949fe85 > --- /dev/null > +++ binutils-2.21.1a/ld/emulparams/msp430uni.sh > @@ -0,0 +1,14 @@ > +#!/bin/sh > + > +# This called by genscripts_extra.sh > + > +MSP430_NAME=3D${EMULATION_NAME} > +ARCH=3Dmsp430 > +SCRIPT_NAME=3Delf32msp430 > +TEMPLATE_NAME=3Dgeneric > +EXTRA_EM_FILE=3Dmsp430 > +OUTPUT_FORMAT=3D"elf32-msp430" > +MACHINE=3D > +MAXPAGESIZE=3D1 > +EMBEDDED=3Dyes > + > diff --git binutils-2.21.1a.orig/ld/emultempl/msp430.em binutils-2.21.1a/= ld/emultempl/msp430.em > new file mode 100644 > index 0000000..f4586f8 > --- /dev/null > +++ binutils-2.21.1a/ld/emultempl/msp430.em > @@ -0,0 +1,107 @@ > +# This shell script emits a C file. -*- C -*- > +# Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. > +# > +# This file is part of the GNU Binutils. > +# > +# 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. > +# > + > +# Adapt genelf.em for MSP430 > +# This file is sourced from generic.em > +# > +fragment < +#include "elf-bfd.h" > +#include "libbfd.h" > +#include "elf/msp430.h" > + > +EOF > +source_em ${srcdir}/emultempl/elf-generic.em > +fragment < + > +static void > +gld${EMULATION_NAME}_after_open (void) > +{ > + bfd *ibfd; > + asection *sec; > + asymbol **syms; > + > + after_open_default (); > + > + if (link_info.relocatable) > + for (ibfd =3D link_info.input_bfds; ibfd !=3D NULL; ibfd =3D ibfd->l= ink_next) > + if ((syms =3D bfd_get_outsymbols (ibfd)) !=3D NULL > + && bfd_get_flavour (ibfd) =3D=3D bfd_target_elf_flavour) > + for (sec =3D ibfd->sections; sec !=3D NULL; sec =3D sec->next) > + if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) =3D=3D SEC_GROUP) > + { > + struct bfd_elf_section_data *sec_data =3D elf_section_data (sec); > + elf_group_id (sec) =3D syms[sec_data->this_hdr.sh_info - 1]; > + } > +} > + > +static void > +gld${EMULATION_NAME}_before_allocation (void) > +{ > + if (link_info.relocatable > + && !_bfd_elf_size_group_sections (&link_info)) > + einfo ("%X%P: can not size group sections: %E\n"); > + before_allocation_default (); > +} > + > +static void > +gld${EMULATION_NAME}_after_allocation (void) > +{ > + gld${EMULATION_NAME}_map_segments (FALSE); > +} > + > +static void > +gld${EMULATION_NAME}_finish (void) > +{ > + bfd *obfd =3D link_info.output_bfd; > + Elf_Internal_Ehdr *o_ehdrp =3D elf_elfheader (obfd); > + unsigned long flags =3D 0; > + bfd *ibfd; > + > + for (ibfd =3D link_info.input_bfds; ibfd !=3D NULL; ibfd =3D ibfd->lin= k_next) { > + Elf_Internal_Ehdr * i_ehdrp =3D elf_elfheader (ibfd); > + > + if (EF_MSP430_UNIARCH & i_ehdrp->e_flags) > + flags |=3D i_ehdrp->e_flags; > + } > + if (EF_MSP430_UNIARCH & flags) { > + int bfd_mach; > + switch (flags & EF_MSP430_ARCH) > + { > + default: > + case EF_MSP430_ARCH_430: > + bfd_mach =3D bfd_mach_msp430; > + break; > + case EF_MSP430_ARCH_430X: > + bfd_mach =3D bfd_mach_msp430x; > + break; > + } > + bfd_default_set_arch_mach (obfd, bfd_arch_msp430, bfd_mach); > + o_ehdrp->e_flags =3D flags; > + } > + finish_default(); > +} > +EOF > +# Put these extra routines in ld_${EMULATION_NAME}_emulation > +# > +LDEMUL_AFTER_OPEN=3Dgld${EMULATION_NAME}_after_open > +LDEMUL_BEFORE_ALLOCATION=3Dgld${EMULATION_NAME}_before_allocation > +LDEMUL_AFTER_ALLOCATION=3Dgld${EMULATION_NAME}_after_allocation > +LDEMUL_FINISH=3Dgld${EMULATION_NAME}_finish > diff --git binutils-2.21.1a.orig/ld/scripttempl/elf32msp430.sc binutils-2= .21.1a/ld/scripttempl/elf32msp430.sc > index cbffe48..08fd422 100644 > --- binutils-2.21.1a.orig/ld/scripttempl/elf32msp430.sc > +++ binutils-2.21.1a/ld/scripttempl/elf32msp430.sc > @@ -1,206 +1,173 @@ > #!/bin/sh >=20=20 > -HEAP_SECTION_MSP430=3D" " > -HEAP_MEMORY_MSP430=3D" " > - > -if test ${GOT_HEAP_MSP-0} -ne 0=20 > -then=20 > -HEAP_SECTION_MSP430=3D".heap ${RELOCATING-0} : > - { > - ${RELOCATING+ PROVIDE (__heap_data_start =3D .) ; } > - *(.heap*) > - ${RELOCATING+ PROVIDE (_heap_data_end =3D .) ; } > - ${RELOCATING+. =3D ALIGN(2);} > - ${RELOCATING+ PROVIDE (__heap_bottom =3D .) ; } > - ${RELOCATING+ PROVIDE (__heap_top =3D ${HEAP_START} + ${HEAP_LENGTH}= ) ; } > - } ${RELOCATING+ > heap}" > -HEAP_MEMORY_MSP430=3D"heap(rwx) : ORIGIN =3D $HEAP_START, LENGTH =3D $= HEAP_LENGTH" > -fi > - > - > cat < -OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}") > -OUTPUT_ARCH(${ARCH}) > +OUTPUT_FORMAT("${OUTPUT_FORMAT}") > +OUTPUT_ARCH("${MSP430_NAME}") >=20=20 > -MEMORY > -{ > - text (rx) : ORIGIN =3D $ROM_START, LENGTH =3D $ROM_SIZE > - data (rwx) : ORIGIN =3D $RAM_START, LENGTH =3D $RAM_SIZE > - vectors (rw) : ORIGIN =3D 0xffe0, LENGTH =3D 0x20 > - bootloader(rx) : ORIGIN =3D 0x0c00, LENGTH =3D 1K > - infomem(rx) : ORIGIN =3D 0x1000, LENGTH =3D 256 > - infomemnobits(rx) : ORIGIN =3D 0x1000, LENGTH =3D 256 > - ${HEAP_MEMORY_MSP430} > -} > +${RELOCATING+INCLUDE "memory.x"} > +${RELOCATING+INCLUDE "periph.x"} >=20=20 > SECTIONS > { > /* Read-only sections, merged into text segment. */ > ${TEXT_DYNAMIC+${DYNAMIC}} > - .hash ${RELOCATING-0} : { *(.hash) } > - .dynsym ${RELOCATING-0} : { *(.dynsym) } > - .dynstr ${RELOCATING-0} : { *(.dynstr) } > - .gnu.version ${RELOCATING-0} : { *(.gnu.version) } > - .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } > - .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } > - > - .rel.init ${RELOCATING-0} : { *(.rel.init) } > + .hash ${RELOCATING-0} : { *(.hash) } > + .dynsym ${RELOCATING-0} : { *(.dynsym) } > + .dynstr ${RELOCATING-0} : { *(.dynstr) } > + .gnu.version ${RELOCATING-0} : { *(.gnu.version) } > + .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } > + .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } > + > + .rel.init ${RELOCATING-0} : { *(.rel.init) } > .rela.init ${RELOCATING-0} : { *(.rela.init) } > - .rel.text ${RELOCATING-0} : > - { > - *(.rel.text) > - ${RELOCATING+*(.rel.text.*)} > - ${RELOCATING+*(.rel.gnu.linkonce.t*)} > - } > - .rela.text ${RELOCATING-0} : > - { > - *(.rela.text) > - ${RELOCATING+*(.rela.text.*)} > - ${RELOCATING+*(.rela.gnu.linkonce.t*)} > - } > - .rel.fini ${RELOCATING-0} : { *(.rel.fini) } > + .rel.fini ${RELOCATING-0} : { *(.rel.fini) } > .rela.fini ${RELOCATING-0} : { *(.rela.fini) } > - .rel.rodata ${RELOCATING-0} : > - { > - *(.rel.rodata) > - ${RELOCATING+*(.rel.rodata.*)} > - ${RELOCATING+*(.rel.gnu.linkonce.r*)} > - } > - .rela.rodata ${RELOCATING-0} : > - { > - *(.rela.rodata) > - ${RELOCATING+*(.rela.rodata.*)} > - ${RELOCATING+*(.rela.gnu.linkonce.r*)} > - } > - .rel.data ${RELOCATING-0} : > - { > - *(.rel.data) > - ${RELOCATING+*(.rel.data.*)} > - ${RELOCATING+*(.rel.gnu.linkonce.d*)} > - } > - .rela.data ${RELOCATING-0} : > - { > - *(.rela.data) > - ${RELOCATING+*(.rela.data.*)} > - ${RELOCATING+*(.rela.gnu.linkonce.d*)} > - } > - .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } > - .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } > - .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } > - .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } > - .rel.got ${RELOCATING-0} : { *(.rel.got) } > - .rela.got ${RELOCATING-0} : { *(.rela.got) } > - .rel.bss ${RELOCATING-0} : { *(.rel.bss) } > - .rela.bss ${RELOCATING-0} : { *(.rela.bss) } > - .rel.plt ${RELOCATING-0} : { *(.rel.plt) } > - .rela.plt ${RELOCATING-0} : { *(.rela.plt) } > - > - /* Internal text space. */ > + > + .rel.text ${RELOCATING-0} : { *(.rel.text${RELOCATING+ .rel.text.* = .rel.gnu.linkonce.t.*}) } > + .rela.text ${RELOCATING-0} : { *(.rela.text${RELOCATING+ .rela.text.= * .rela.gnu.linkonce.t.*}) } > + .rel.rodata ${RELOCATING-0} : { *(.rel.rodata${RELOCATING+ .rel.rodat= a.* .rel.gnu.linkonce.r.*}) } > + .rela.rodata ${RELOCATING-0} : { *(.rela.rodata${RELOCATING+ .rela.rod= ata.* .rela.gnu.linkonce.r.*}) } > + .rel.data ${RELOCATING-0} : { *(.rel.data${RELOCATING+ .rel.data.* = .rel.gnu.linkonce.d.*}) } > + .rela.data ${RELOCATING-0} : { *(.rela.data${RELOCATING+ .rela.data.= * .rela.gnu.linkonce.d.*}) } > + .rel.bss ${RELOCATING-0} : { *(.rel.bss${RELOCATING+ .rel.bss.* .r= el.gnu.linkonce.b.*}) } > + .rela.bss ${RELOCATING-0} : { *(.rela.bss${RELOCATING+ .rela.bss.* = .rela.gnu.linkonce.b.*}) } > + > + .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } > + .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } > + .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } > + .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } > + .rel.got ${RELOCATING-0} : { *(.rel.got) } > + .rela.got ${RELOCATING-0} : { *(.rela.got) } > + .rel.plt ${RELOCATING-0} : { *(.rel.plt) } > + .rela.plt ${RELOCATING-0} : { *(.rela.plt) } > + > .text : > { > - ${RELOCATING+. =3D ALIGN(2);} > - *(.init) > - *(.init0) /* Start here after reset. */ > - *(.init1) > - *(.init2) /* Copy data loop */ > - *(.init3) > - *(.init4) /* Clear bss */ > - *(.init5) > - *(.init6) /* C++ constructors. */ > - *(.init7) > - *(.init8) > - *(.init9) /* Call main(). */ > - > + ${RELOCATING+ . =3D ALIGN(2);} > + ${RELOCATING+ KEEP(*(.init .init.*)) } > + ${RELOCATING+ KEEP(*(.init0)) /* Start here after reset. = */ } > + ${RELOCATING+ KEEP(*(.init1)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.init2)) /* Initialize stack. = */ } > + ${RELOCATING+ KEEP(*(.init3)) /* Initialize hardware, user definabl= e. */ } > + ${RELOCATING+ KEEP(*(.init4)) /* Copy data to .data, clear bss. = */ } > + ${RELOCATING+ KEEP(*(.init5)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.init6)) /* C++ constructors. = */ } > + ${RELOCATING+ KEEP(*(.init7)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.init8)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.init9)) /* Call main(). = */ } > + ${RELOCATING+ KEEP(*(.fini9)) /* Falls into here after main(). User= definable. */ } > + ${RELOCATING+ KEEP(*(.fini8)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.fini7)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.fini6)) /* C++ destructors. = */ } > + ${RELOCATING+ KEEP(*(.fini5)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.fini4)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.fini3)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.fini2)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.fini1)) /* User definable. = */ } > + ${RELOCATING+ KEEP(*(.fini0)) /* Infinite loop after program termin= ation. */ } > + ${RELOCATING+ KEEP(*(.fini .fini.*))} > + > + ${CONSTRUCTING+ . =3D ALIGN(2); } > ${CONSTRUCTING+ __ctors_start =3D . ; } > - ${CONSTRUCTING+ *(.ctors) } > + ${CONSTRUCTING+ KEEP(*(.ctors)) } > ${CONSTRUCTING+ __ctors_end =3D . ; } > ${CONSTRUCTING+ __dtors_start =3D . ; } > - ${CONSTRUCTING+ *(.dtors) } > + ${CONSTRUCTING+ KEEP(*(.dtors)) } > ${CONSTRUCTING+ __dtors_end =3D . ; } >=20=20 > - ${RELOCATING+. =3D ALIGN(2);} > - *(.text) > - ${RELOCATING+. =3D ALIGN(2);} > - *(.text.*) > - > - ${RELOCATING+. =3D ALIGN(2);} > - *(.fini9) /* */ > - *(.fini8) > - *(.fini7) > - *(.fini6) /* C++ destructors. */ > - *(.fini5) > - *(.fini4) > - *(.fini3) > - *(.fini2) > - *(.fini1) > - *(.fini0) /* Infinite loop after program termination. */ > - *(.fini) > - > - _etext =3D .; > - } ${RELOCATING+ > text} > - > - .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text)= )} > + ${RELOCATING+ . =3D ALIGN(2);} > + *(.text${RELOCATING+ .text.* .gnu.linkonce.t.*}) > + ${RELOCATING+ . =3D ALIGN(2);} > + } ${RELOCATING+ > REGION_TEXT} > + > + .rodata ${RELOCATING-0} : > + { > + ${RELOCATING+ . =3D ALIGN(2);} > + *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) > + ${RELOCATING+ . =3D ALIGN(2);} > + } ${RELOCATING+ > REGION_TEXT} > + ${RELOCATING+ _etext =3D .;} /* Past last read-only (loadable) segment= */ > +=20=20 > + .data ${RELOCATING-0} : > {=20=20 > + ${RELOCATING+ . =3D ALIGN(2);} > ${RELOCATING+ PROVIDE (__data_start =3D .) ; } > - ${RELOCATING+. =3D ALIGN(2);} > - *(.data) > - ${RELOCATING+. =3D ALIGN(2);} > - *(.gnu.linkonce.d*) > - ${RELOCATING+. =3D ALIGN(2);} > - ${RELOCATING+ _edata =3D . ; } > - } ${RELOCATING+ > data} > + *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*}) > + ${RELOCATING+ . =3D ALIGN(2);} > + ${RELOCATING+ _edata =3D . ; } /* Past last read-write (loadable) se= gment */ > + } ${RELOCATING+ > REGION_DATA AT > REGION_TEXT} > + ${RELOCATING+ PROVIDE (__data_load_start =3D LOADADDR(.data) ); } > + ${RELOCATING+ PROVIDE (__data_size =3D SIZEOF(.data) ); } >=20=20=20=20 > - /* Bootloader. */ > - .bootloader ${RELOCATING-0} : > + .bss ${RELOCATING-0} : > { > - ${RELOCATING+ PROVIDE (__boot_start =3D .) ; } > - *(.bootloader) > - ${RELOCATING+. =3D ALIGN(2);} > - *(.bootloader.*) > - } ${RELOCATING+ > bootloader} > -=20=20 > - /* Information memory. */ > + ${RELOCATING+ PROVIDE (__bss_start =3D .) ; } > + *(.bss${RELOCATING+ .bss.*}) > + *(COMMON) > + ${RELOCATING+ . =3D ALIGN(2);} > + ${RELOCATING+ PROVIDE (__bss_end =3D .) ; } > + } ${RELOCATING+ > REGION_DATA} > + ${RELOCATING+ PROVIDE (__bss_size =3D SIZEOF(.bss) ); } > + > + .noinit ${RELOCATING-0} : > + { > + ${RELOCATING+ PROVIDE (__noinit_start =3D .) ; } > + *(.noinit${RELOCATING+ .noinit.*}) > + ${RELOCATING+ . =3D ALIGN(2);} > + ${RELOCATING+ PROVIDE (__noinit_end =3D .) ; } > + } ${RELOCATING+ > REGION_DATA} > + ${RELOCATING+ . =3D ALIGN(2);} > + ${RELOCATING+ _end =3D . ; } /* Past last write (loadable) segment */ > + > .infomem ${RELOCATING-0} : > { > *(.infomem) > - ${RELOCATING+. =3D ALIGN(2);} > + ${RELOCATING+ . =3D ALIGN(2);} > *(.infomem.*) > } ${RELOCATING+ > infomem} >=20=20 > - /* Information memory (not loaded into MPU). */ > .infomemnobits ${RELOCATING-0} : > { > *(.infomemnobits) > - ${RELOCATING+. =3D ALIGN(2);} > + ${RELOCATING+ . =3D ALIGN(2);} > *(.infomemnobits.*) > - } ${RELOCATING+ > infomemnobits} > + } ${RELOCATING+ > infomem} >=20=20 > - .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : > + .infoa ${RELOCATING-0} : > { > - ${RELOCATING+ PROVIDE (__bss_start =3D .) ; } > - *(.bss) > - *(COMMON) > - ${RELOCATING+ PROVIDE (__bss_end =3D .) ; } > - ${RELOCATING+ _end =3D . ; } > - } ${RELOCATING+ > data} > + *(.infoa${RELOCATING+ .infoa.*}) > + } ${RELOCATING+ > infoa} >=20=20 > - .noinit ${RELOCATING+ SIZEOF(.bss) + ADDR(.bss)} : > + .infob ${RELOCATING-0} : > { > - ${RELOCATING+ PROVIDE (__noinit_start =3D .) ; } > - *(.noinit) > - *(COMMON) > - ${RELOCATING+ PROVIDE (__noinit_end =3D .) ; } > - ${RELOCATING+ _end =3D . ; } > - } ${RELOCATING+ > data} > + *(.infob${RELOCATING+ .infob.*}) > + } ${RELOCATING+ > infob} > + > + .infoc ${RELOCATING-0} : > + { > + *(.infoc${RELOCATING+ .infoc.*}) > + } ${RELOCATING+ > infoc} > + > + .infod ${RELOCATING-0} : > + { > + *(.infod${RELOCATING+ .infod.*}) > + } ${RELOCATING+ > infod} >=20=20 > .vectors ${RELOCATING-0}: > { > ${RELOCATING+ PROVIDE (__vectors_start =3D .) ; } > - *(.vectors*) > + KEEP(*(.vectors*)) > ${RELOCATING+ _vectors_end =3D . ; } > } ${RELOCATING+ > vectors} >=20=20 > - ${HEAP_SECTION_MSP430} > + .fartext : > + { > + ${RELOCATING+ . =3D ALIGN(2);} > + *(.fartext) > + ${RELOCATING+ . =3D ALIGN(2);} > + *(.fartext.*) > + ${RELOCATING+ _efartext =3D .;} > + } ${RELOCATING+ > REGION_FAR_ROM} >=20=20 > /* Stabs for profiling information*/ > .profiler 0 : { *(.profiler) } > @@ -239,11 +206,12 @@ SECTIONS > .debug_loc 0 : { *(.debug_loc) } > .debug_macinfo 0 : { *(.debug_macinfo) } >=20=20 > - PROVIDE (__stack =3D ${STACK}) ; > - PROVIDE (__data_start_rom =3D _etext) ; > - PROVIDE (__data_end_rom =3D _etext + SIZEOF (.data)) ; > - PROVIDE (__noinit_start_rom =3D _etext + SIZEOF (.data)) ; > - PROVIDE (__noinit_end_rom =3D _etext + SIZEOF (.data) + SIZEOF (.noini= t)) ; > - PROVIDE (__subdevice_has_heap =3D ${GOT_HEAP_MSP-0}) ; > + /* DWARF 3 */ > + .debug_pubtypes 0 : { *(.debug_pubtypes) } > + .debug_ranges 0 : { *(.debug_ranges) } > + > + ${RELOCATING+ PROVIDE (__stack =3D ORIGIN(ram) + LENGTH(ram));} > + ${RELOCATING+ PROVIDE (__data_start_rom =3D _etext);} > + ${RELOCATING+ PROVIDE (__data_end_rom =3D _etext + SIZEOF (.data));} > } > EOF > diff --git binutils-2.21.1a.orig/ld/scripttempl/elf32msp430_3.sc binutils= -2.21.1a/ld/scripttempl/elf32msp430_3.sc > deleted file mode 100644 > index 15eb517..0000000 > --- binutils-2.21.1a.orig/ld/scripttempl/elf32msp430_3.sc > +++ /dev/null > @@ -1,192 +0,0 @@ > -cat < -OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}") > -OUTPUT_ARCH(${ARCH}) > - > -MEMORY > -{ > - text (rx) : ORIGIN =3D $ROM_START, LENGTH =3D $ROM_SIZE > - data (rwx) : ORIGIN =3D $RAM_START, LENGTH =3D $RAM_SIZE > - vectors (rw) : ORIGIN =3D 0xffe0, LENGTH =3D 0x20 > -} > - > -SECTIONS > -{ > - /* Read-only sections, merged into text segment. */ > - ${TEXT_DYNAMIC+${DYNAMIC}} > - .hash ${RELOCATING-0} : { *(.hash) } > - .dynsym ${RELOCATING-0} : { *(.dynsym) } > - .dynstr ${RELOCATING-0} : { *(.dynstr) } > - .gnu.version ${RELOCATING-0} : { *(.gnu.version) } > - .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } > - .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } > - > - .rel.init ${RELOCATING-0} : { *(.rel.init) } > - .rela.init ${RELOCATING-0} : { *(.rela.init) } > - .rel.text ${RELOCATING-0} : > - { > - *(.rel.text) > - ${RELOCATING+*(.rel.text.*)} > - ${RELOCATING+*(.rel.gnu.linkonce.t*)} > - } > - .rela.text ${RELOCATING-0} : > - { > - *(.rela.text) > - ${RELOCATING+*(.rela.text.*)} > - ${RELOCATING+*(.rela.gnu.linkonce.t*)} > - } > - .rel.fini ${RELOCATING-0} : { *(.rel.fini) } > - .rela.fini ${RELOCATING-0} : { *(.rela.fini) } > - .rel.rodata ${RELOCATING-0} : > - { > - *(.rel.rodata) > - ${RELOCATING+*(.rel.rodata.*)} > - ${RELOCATING+*(.rel.gnu.linkonce.r*)} > - } > - .rela.rodata ${RELOCATING-0} : > - { > - *(.rela.rodata) > - ${RELOCATING+*(.rela.rodata.*)} > - ${RELOCATING+*(.rela.gnu.linkonce.r*)} > - } > - .rel.data ${RELOCATING-0} : > - { > - *(.rel.data) > - ${RELOCATING+*(.rel.data.*)} > - ${RELOCATING+*(.rel.gnu.linkonce.d*)} > - } > - .rela.data ${RELOCATING-0} : > - { > - *(.rela.data) > - ${RELOCATING+*(.rela.data.*)} > - ${RELOCATING+*(.rela.gnu.linkonce.d*)} > - } > - .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } > - .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } > - .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } > - .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } > - .rel.got ${RELOCATING-0} : { *(.rel.got) } > - .rela.got ${RELOCATING-0} : { *(.rela.got) } > - .rel.bss ${RELOCATING-0} : { *(.rel.bss) } > - .rela.bss ${RELOCATING-0} : { *(.rela.bss) } > - .rel.plt ${RELOCATING-0} : { *(.rel.plt) } > - .rela.plt ${RELOCATING-0} : { *(.rela.plt) } > - > - /* Internal text space. */ > - .text : > - { > - ${RELOCATING+. =3D ALIGN(2);} > - *(.init) > - *(.init0) /* Start here after reset. */ > - *(.init1) > - *(.init2) > - *(.init3) > - *(.init4) > - *(.init5) > - *(.init6) /* C++ constructors. */ > - *(.init7) > - *(.init8) > - *(.init9) /* Call main(). */ > - > - ${CONSTRUCTING+ __ctors_start =3D . ; } > - ${CONSTRUCTING+ *(.ctors) } > - ${CONSTRUCTING+ __ctors_end =3D . ; } > - ${CONSTRUCTING+ __dtors_start =3D . ; } > - ${CONSTRUCTING+ *(.dtors) } > - ${CONSTRUCTING+ __dtors_end =3D . ; } > - > - ${RELOCATING+. =3D ALIGN(2);} > - *(.text) > - ${RELOCATING+. =3D ALIGN(2);} > - *(.text.*) > - > - ${RELOCATING+. =3D ALIGN(2);} > - *(.fini9) > - *(.fini8) > - *(.fini7) > - *(.fini6) /* C++ destructors. */ > - *(.fini5) > - *(.fini4) > - *(.fini3) > - *(.fini2) > - *(.fini1) > - *(.fini0) /* Infinite loop after program termination. */ > - *(.fini) > - > - ${RELOCATING+ _etext =3D . ; } > - } ${RELOCATING+ > text} > - > - .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text)= )} > - {=20=20 > - ${RELOCATING+ PROVIDE (__data_start =3D .) ; } > - *(.data) > - *(.gnu.linkonce.d*) > - ${RELOCATING+. =3D ALIGN(2);} > - ${RELOCATING+ _edata =3D . ; } > - } ${RELOCATING+ > data} > -=20=20 > - .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : > - { > - ${RELOCATING+ PROVIDE (__bss_start =3D .) ; } > - *(.bss) > - *(COMMON) > - ${RELOCATING+ PROVIDE (__bss_end =3D .) ; } > - ${RELOCATING+ _end =3D . ; } > - } ${RELOCATING+ > data} > - > - .noinit ${RELOCATING+ SIZEOF(.bss) + ADDR(.bss)} : > - { > - ${RELOCATING+ PROVIDE (__noinit_start =3D .) ; } > - *(.noinit) > - *(COMMON) > - ${RELOCATING+ PROVIDE (__noinit_end =3D .) ; } > - ${RELOCATING+ _end =3D . ; } > - } ${RELOCATING+ > data} > - > - .vectors ${RELOCATING-0}: > - { > - ${RELOCATING+ PROVIDE (__vectors_start =3D .) ; } > - *(.vectors*) > - ${RELOCATING+ _vectors_end =3D . ; } > - } ${RELOCATING+ > vectors} > - > - /* Stabs debugging sections. */ > - .stab 0 : { *(.stab) }=20 > - .stabstr 0 : { *(.stabstr) } > - .stab.excl 0 : { *(.stab.excl) } > - .stab.exclstr 0 : { *(.stab.exclstr) } > - .stab.index 0 : { *(.stab.index) } > - .stab.indexstr 0 : { *(.stab.indexstr) } > - .comment 0 : { *(.comment) } > -=20 > - /* DWARF debug sections. > - Symbols in the DWARF debugging sections are relative to the beginni= ng > - of the section so we begin them at 0. */ > - > - /* DWARF 1 */ > - .debug 0 : { *(.debug) } > - .line 0 : { *(.line) } > - > - /* GNU DWARF 1 extensions */ > - .debug_srcinfo 0 : { *(.debug_srcinfo) } > - .debug_sfnames 0 : { *(.debug_sfnames) } > - > - /* DWARF 1.1 and DWARF 2 */ > - .debug_aranges 0 : { *(.debug_aranges) } > - .debug_pubnames 0 : { *(.debug_pubnames) } > - > - /* DWARF 2 */ > - .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } > - .debug_abbrev 0 : { *(.debug_abbrev) } > - .debug_line 0 : { *(.debug_line) } > - .debug_frame 0 : { *(.debug_frame) } > - .debug_str 0 : { *(.debug_str) } > - .debug_loc 0 : { *(.debug_loc) } > - .debug_macinfo 0 : { *(.debug_macinfo) } > - > - PROVIDE (__stack =3D ${STACK}) ; > - PROVIDE (__data_start_rom =3D _etext) ; > - PROVIDE (__data_end_rom =3D _etext + SIZEOF (.data)) ; > - PROVIDE (__noinit_start_rom =3D _etext + SIZEOF (.data)) ; > - PROVIDE (__noinit_end_rom =3D _etext + SIZEOF (.data) + SIZEOF (.noini= t)) ; > -} > -EOF > diff --git binutils-2.21.1a.orig/opcodes/msp430-dis.c binutils-2.21.1a/op= codes/msp430-dis.c > index 9d7edbe..4e0dd91 100644 > --- binutils-2.21.1a.orig/opcodes/msp430-dis.c > +++ binutils-2.21.1a/opcodes/msp430-dis.c > @@ -34,11 +34,8 @@ > #include "opcode/msp430.h" > #undef DASM_SECTION >=20=20 > - > -#define PS(x) (0xffff & (x)) > - > static unsigned short > -msp430dis_opcode (bfd_vma addr, disassemble_info *info) > +msp430dis_opcode (bfd_vma addr, disassemble_info * info) > { > bfd_byte buffer[2]; > int status; > @@ -52,12 +49,174 @@ msp430dis_opcode (bfd_vma addr, disassemble_info *in= fo) > return bfd_getl16 (buffer); > } >=20=20 > +static unsigned short > +msp430dis_operand (bfd_vma addr, disassemble_info * info, int reg, int a= m, > + int *cmd_len) > +{ > + static int const op_length[][5] =3D { > + /* PC SP r2 r3 rN AM */ > + {0, 0, 0, 0, 0}, /* 0 =3D AM_Register: Rn */ > + {2, 2, 2, 0, 2}, /* 1 =3D AM_Indexed: x(Rn) */ > + {0, 0, 0, 0, 0}, /* 2 =3D AMs_IndirectRegister: @Rn */ > + {2, 0, 0, 0, 0}, /* 3 =3D AMs_IndirectAutoIncrement: @Rn+ */ > + }; > + if (reg >=3D (int) (sizeof (op_length[0]) / sizeof (op_length[0][0]))) > + reg =3D sizeof (op_length[0]) / sizeof (op_length[0][0]) - 1; > + > + if (op_length[am][reg]) > + { > + bfd_byte buffer[2]; > + int status =3D info->read_memory_func (addr, buffer, 2, info); > + if (status !=3D 0) > + { > + info->memory_error_func (status, addr, info); > + return -1; > + } > + *cmd_len +=3D 2; > + return bfd_getl16 (buffer); > + } > + return 0; > +} > + > +typedef enum > +{ > + OP_OTHER =3D 0, > + OP_DECIMAL =3D 0x03, > + OP_16BIT =3D 0x04, > + OP_20BIT =3D 0x05, > + OP_MASK_BITS =3D 0x07, > + OP_IS_HEX =3D 0x08, > + OP_16BIT_HEX =3D OP_16BIT | OP_IS_HEX, > + OP_20BIT_HEX =3D OP_20BIT | OP_IS_HEX, > + OP_IS_430X_INSN =3D 0x10, > +} operand_t; > + > +static void > +msp430_decode_operand (int reg, int am, int op_addr, int dst, operand_t = size, > + char *op, char *comm) > +{ > + int is_hex =3D size & OP_IS_HEX; > + int is_430x =3D size & OP_IS_430X_INSN; > + size =3D size & OP_MASK_BITS; > +=20=20 > + if (NULL =3D=3D op) > + return; > + switch (am) > + { > + case AM_Register: > + if (reg =3D=3D REGNO_CG2) /* #0 */ > + { > + sprintf (op, "#0"); > + sprintf (comm, "r3 As=3D=3D00"); > + } > + else > + sprintf (op, "r%d", reg); > + break; > + case AM_Indexed: > + if (reg =3D=3D REGNO_PC) /* Symbolic: ADDR */ > + { > + int mem_addr; > +=09=20=20 > + mem_addr =3D op_addr + dst; > + if (!is_430x && size =3D=3D OP_16BIT) > + { > + if (MASK_16 (op_addr) =3D=3D op_addr) > + mem_addr =3D MASK_16 (mem_addr); > + sprintf (comm, "PC rel. 0x%04x", MASK_16 (mem_addr)); > + } > + else > + sprintf (comm, "PC rel. 0x%05x", MASK_20 (mem_addr)); > + sprintf (op, "%d(r0)", dst); > + } > + else if (reg =3D=3D REGNO_CG1) /* Absolute: &ADDR */ > + { > + if (size =3D=3D OP_20BIT) > + sprintf (op, "&0x%05x", MASK_20 (dst)); > + else > + sprintf (op, "&0x%04x", MASK_16 (dst)); > + } > + else if (reg =3D=3D REGNO_CG2) /* #1 */ > + { > + sprintf (op, "#1"); > + sprintf (comm, "r3 As=3D=3D01"); > + } > + else /* Indexed: x(Rn) */ > + { > + sprintf (op, "%d(r%d)", dst, reg); > + if (size =3D=3D OP_20BIT) > + sprintf (comm, "0x%05x(r%d)", MASK_20 (dst), reg); > + else > + sprintf (comm, "0x%04x(r%d)", MASK_16 (dst), reg); > + } > + break; > + case AMs_IndirectRegister: > + if (reg =3D=3D REGNO_CG1) /* #4 */ > + { > + sprintf (op, "#4"); > + sprintf (comm, "r2 As=3D=3D10"); > + } > + else if (reg =3D=3D REGNO_CG2) /* #2 */ > + { > + sprintf (op, "#2"); > + sprintf (comm, "r3 As=3D=3D10"); > + } > + else /* @Rn */ > + sprintf (op, "@r%d", reg); > + break; > + case AMs_IndirectAutoIncrement: > + switch (reg) > + { > + case REGNO_PC: /* #N */ > + if (OP_16BIT =3D=3D size) > + { > + if (is_hex) > + sprintf (op, "#0x%04x", MASK_16 (dst)); > + else > + { > + sprintf (op, "#%d", dst); > + sprintf (comm, "#0x%04x", MASK_16 (dst)); > + } > + } > + else if (OP_20BIT =3D=3D size) > + { > + if (is_hex) > + sprintf (op, "#0x%05x", MASK_20 (dst)); > + else > + { > + sprintf (op, "#%d", dst); > + sprintf (comm, "#0x%05x", MASK_20 (dst)); > + } > + } > + else > + sprintf (op, "#%d", dst); > + break; > + case REGNO_CG1: /* #8 */ > + sprintf (op, "#8"); > + sprintf (comm, "r2 As=3D=3D11"); > + break; > + case REGNO_CG2: /* #-1 */ > + sprintf (op, "#-1"); > + sprintf (comm, "r3 As=3D=3D11"); > + break; > + default: /* @Rn+ */ > + sprintf (op, "@r%d+", reg); > + break; > + } > + break; > + } > +} > + > +static void > +msp430x_decode_operand (int reg, int am, int op_addr, int dst, operand_t= size, > + char *op, char *comm) > +{ > + msp430_decode_operand (reg, am, op_addr, dst, OP_IS_430X_INSN | size, = op, comm); > +} > + > static int > -msp430_nooperands (struct msp430_opcode_s *opcode, > +msp430_nooperands (struct msp430_opcode_s const *opcode, > bfd_vma addr ATTRIBUTE_UNUSED, > - unsigned short insn ATTRIBUTE_UNUSED, > - char *comm, > - int *cycles) > + unsigned short insn ATTRIBUTE_UNUSED, char *comm) > { > /* Pop with constant. */ > if (insn =3D=3D 0x43b2) > @@ -65,35 +224,27 @@ msp430_nooperands (struct msp430_opcode_s *opcode, > if (insn =3D=3D opcode->bin_opcode) > return 2; >=20=20 > - if (opcode->fmt =3D=3D 0) > + if (opcode_format (opcode) =3D=3D FMT_EMULATED) > { > if ((insn & 0x0f00) !=3D 3 || (insn & 0x0f00) !=3D 2) > return 0; >=20=20 > strcpy (comm, "emulated..."); > - *cycles =3D 1; > } > else > - { > - strcpy (comm, "return from interupt"); > - *cycles =3D 5; > - } > + strcpy (comm, "return from interupt"); >=20=20 > return 2; > } >=20=20 > static int > -msp430_singleoperand (disassemble_info *info, > - struct msp430_opcode_s *opcode, > - bfd_vma addr, > - unsigned short insn, > - char *op, > - char *comm, > - int *cycles) > +msp430_singleoperand (disassemble_info * info, > + struct msp430_opcode_s const *opcode, > + bfd_vma addr, unsigned short insn, char *op, char *comm) > { > int regs =3D 0, regd =3D 0; > int ad =3D 0, as =3D 0; > - int where =3D 0; > + bfd_vma op_addr; > int cmd_len =3D 2; > short dst =3D 0; >=20=20 > @@ -102,10 +253,11 @@ msp430_singleoperand (disassemble_info *info, > as =3D (insn & 0x0030) >> 4; > ad =3D (insn & 0x0080) >> 7; >=20=20 > - switch (opcode->fmt) > + op_addr =3D addr + cmd_len; > + switch (opcode_format (opcode)) > { > - case 0: /* Emulated work with dst register. */ > - if (regs !=3D 2 && regs !=3D 3 && regs !=3D 1) > + case FMT_EMULATED: /* Emulated work with dst register. */ > + if (regs !=3D REGNO_CG1 && regs !=3D REGNO_CG2 && regs !=3D REGNO_= SP) > return 0; >=20=20 > /* Check if not clr insn. */ > @@ -113,170 +265,30 @@ msp430_singleoperand (disassemble_info *info, > return 0; >=20=20 > /* Check if really inc, incd insns. */ > - if ((opcode->bin_opcode & 0xff00) =3D=3D 0x5300 && as =3D=3D 3) > + if ((opcode->bin_opcode & 0xff00) =3D=3D 0x5300 > + && as =3D=3D AMs_IndirectAutoIncrement) > return 0; >=20=20 > - if (ad =3D=3D 0) > - { > - *cycles =3D 1; > - > - /* Register. */ > - if (regd =3D=3D 0) > - { > - *cycles +=3D 1; > - sprintf (op, "r0"); > - } > - else if (regd =3D=3D 1) > - sprintf (op, "r1"); > - > - else if (regd =3D=3D 2) > - sprintf (op, "r2"); > - > - else > - sprintf (op, "r%d", regd); > - } > - else /* ad =3D=3D 1 msp430dis_opcode. */ > - { > - if (regd =3D=3D 0) > - { > - /* PC relative. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - *cycles =3D 4; > - sprintf (op, "0x%04x", dst); > - sprintf (comm, "PC rel. abs addr 0x%04x", > - PS ((short) (addr + 2) + dst)); > - } > - else if (regd =3D=3D 2) > - { > - /* Absolute. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - *cycles =3D 4; > - sprintf (op, "&0x%04x", PS (dst)); > - } > - else > - { > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - *cycles =3D 4; > - sprintf (op, "%d(r%d)", dst, regd); > - } > - } > + dst =3D msp430dis_operand (op_addr, info, regd, ad, &cmd_len); > + msp430_decode_operand (regd, ad, op_addr, dst, OP_16BIT, op, comm); > break; >=20=20 > - case 2: /* rrc, push, call, swpb, rra, sxt, push, call, reti etc... = */ > - if (as =3D=3D 0) > - { > - if (regd =3D=3D 3) > - { > - /* Constsnts. */ > - sprintf (op, "#0"); > - sprintf (comm, "r3 As=3D=3D00"); > - } > - else > - { > - /* Register. */ > - sprintf (op, "r%d", regd); > - } > - *cycles =3D 1; > - } > - else if (as =3D=3D 2) > - { > - *cycles =3D 1; > - if (regd =3D=3D 2) > - { > - sprintf (op, "#4"); > - sprintf (comm, "r2 As=3D=3D10"); > - } > - else if (regd =3D=3D 3) > - { > - sprintf (op, "#2"); > - sprintf (comm, "r3 As=3D=3D10"); > - } > - else > - { > - *cycles =3D 3; > - /* Indexed register mode @Rn. */ > - sprintf (op, "@r%d", regd); > - } > - } > - else if (as =3D=3D 3) > - { > - *cycles =3D 1; > - if (regd =3D=3D 2) > - { > - sprintf (op, "#8"); > - sprintf (comm, "r2 As=3D=3D11"); > - } > - else if (regd =3D=3D 3) > - { > - sprintf (op, "#-1"); > - sprintf (comm, "r3 As=3D=3D11"); > - } > - else if (regd =3D=3D 0) > - { > - *cycles =3D 3; > - /* absolute. @pc+ */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op, "#%d", dst); > - sprintf (comm, "#0x%04x", PS (dst)); > - } > - else > - { > - *cycles =3D 3; > - sprintf (op, "@r%d+", regd); > - } > - } > - else if (as =3D=3D 1) > - { > - *cycles =3D 4; > - if (regd =3D=3D 0) > - { > - /* PC relative. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op, "0x%04x", PS (dst)); > - sprintf (comm, "PC rel. 0x%04x", > - PS ((short) addr + 2 + dst)); > - } > - else if (regd =3D=3D 2) > - { > - /* Absolute. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op, "&0x%04x", PS (dst)); > - } > - else if (regd =3D=3D 3) > - { > - *cycles =3D 1; > - sprintf (op, "#1"); > - sprintf (comm, "r3 As=3D=3D01"); > - } > - else > - { > - /* Indexd. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op, "%d(r%d)", dst, regd); > - } > - } > + case FMT_SINGLE_OPERAND: /* rrc, push, call, swpb, rra, sxt, push, c= all, reti etc... */ > + dst =3D msp430dis_operand (op_addr, info, regd, as, &cmd_len); > + if (opcode_variant (opcode) !=3D V_CALL) > + msp430_decode_operand (regd, as, op_addr, dst, OP_16BIT, op, comm); > + else > + msp430_decode_operand (regd, as, op_addr, dst, OP_16BIT_HEX, > + op, comm); > break; >=20=20 > - case 3: /* Jumps. */ > - where =3D insn & 0x03ff; > - if (where & 0x200) > - where |=3D ~0x03ff; > - if (where > 512 || where < -511) > - return 0; > - > - where *=3D 2; > - sprintf (op, "$%+-8d", where + 2); > - sprintf (comm, "abs 0x%x", PS ((short) (addr) + 2 + where)); > - *cycles =3D 2; > - return 2; > + case FMT_JUMP: /* Jumps. */ > + /* sign extension, word addr to byte addr conversion */ > + dst =3D (short) ((insn & 0x03ff) << 6) >> 5; > + sprintf (op, "$%+-8d", dst + cmd_len); > + sprintf (comm, "abs 0x%x", MASK_16 ((short) op_addr + dst)); > break; > + > default: > cmd_len =3D 0; > } > @@ -285,468 +297,538 @@ msp430_singleoperand (disassemble_info *info, > } >=20=20 > static int > -msp430_doubleoperand (disassemble_info *info, > - struct msp430_opcode_s *opcode, > +msp430_doubleoperand (disassemble_info * info, > + struct msp430_opcode_s const *opcode, > bfd_vma addr, > unsigned short insn, > - char *op1, > - char *op2, > - char *comm1, > - char *comm2, > - int *cycles) > + char *op1, char *op2, char *comm1, char *comm2) > { > int regs =3D 0, regd =3D 0; > int ad =3D 0, as =3D 0; > int cmd_len =3D 2; > - short dst =3D 0; > + bfd_vma ops_addr; > + bfd_vma opd_addr; > + short ops; > + short opd; >=20=20 > regd =3D insn & 0x0f; > regs =3D (insn & 0x0f00) >> 8; > as =3D (insn & 0x0030) >> 4; > ad =3D (insn & 0x0080) >> 7; >=20=20 > - if (opcode->fmt =3D=3D 0) > + ops_addr =3D addr + cmd_len; > + if (opcode_format (opcode) =3D=3D FMT_EMULATED) > { > /* Special case: rla and rlc are the only 2 emulated instructions = that > - fall into two operand instructions. */ > + fall into two operand instructions. */ > /* With dst, there are only: > - Rm Register, > - x(Rm) Indexed, > - 0xXXXX Relative, > - &0xXXXX Absolute=20 > + Rm Register, > + x(Rm) Indexed, > + 0xXXXX Relative, > + &0xXXXX Absolute=20 > emulated_ins dst > basic_ins dst, dst. */ >=20=20 > if (regd !=3D regs || as !=3D ad) > return 0; /* May be 'data' section. */ >=20=20 > - if (ad =3D=3D 0) > + if (ad =3D=3D 0 && regd =3D=3D 3) /* #N */ > { > - /* Register mode. */ > - if (regd =3D=3D 3) > - { > - strcpy (comm1, _("Illegal as emulation instr")); > - return -1; > - } > - > - sprintf (op1, "r%d", regd); > - *cycles =3D 1; > + strcpy (comm1, _("Illegal as emulation instr")); > + return -1; > } > - else /* ad =3D=3D 1 */ > - { > - if (regd =3D=3D 0) > - { > - /* PC relative, Symbolic. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 4; > - *cycles =3D 6; > - sprintf (op1, "0x%04x", PS (dst)); > - sprintf (comm1, "PC rel. 0x%04x", > - PS ((short) addr + 2 + dst)); > + ops =3D msp430dis_operand (ops_addr, info, regs, as, &cmd_len); > + opd_addr =3D addr + cmd_len; > + opd =3D msp430dis_operand (opd_addr, info, regd, ad, &cmd_len); >=20=20 > - } > - else if (regd =3D=3D 2) > - { > - /* Absolute. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - /* If the 'src' field is not the same as the dst > - then this is not an rla instruction. */ > - if (dst !=3D msp430dis_opcode (addr + 4, info)) > - return 0; > - cmd_len +=3D 4; > - *cycles =3D 6; > - sprintf (op1, "&0x%04x", PS (dst)); > - } > - else > - { > - /* Indexed. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 4; > - *cycles =3D 6; > - sprintf (op1, "%d(r%d)", dst, regd); > - } > - } > + /* If the 'src' field is not the same as the dst > + then this is not an rla instruction. > + TODO: That assertion is false for symbolics. */ > + if (ops !=3D opd) > + return 0; > + msp430_decode_operand (regs, as, ops_addr, ops, OP_16BIT, op1, com= m1); >=20=20 > *op2 =3D 0; > *comm2 =3D 0; > return cmd_len; > } > - > /* Two operands exactly. */ > - if (ad =3D=3D 0 && regd =3D=3D 3) > + > + if (ad =3D=3D AM_Register && regd =3D=3D REGNO_CG2) > { > - /* R2/R3 are illegal as dest: may be data section. */ > + /* R3 is illegal as dest: may be data section. */ > strcpy (comm1, _("Illegal as 2-op instr")); > return -1; > } > + ops =3D msp430dis_operand (ops_addr, info, regs, as, &cmd_len); > + opd_addr =3D addr + cmd_len; > + opd =3D msp430dis_operand (opd_addr, info, regd, ad, &cmd_len); >=20=20 > - /* Source. */ > - if (as =3D=3D 0) > - { > - *cycles =3D 1; > - if (regs =3D=3D 3) > - { > - /* Constsnts. */ > - sprintf (op1, "#0"); > - sprintf (comm1, "r3 As=3D=3D00"); > - } > - else > - { > - /* Register. */ > - sprintf (op1, "r%d", regs); > - } > - } > - else if (as =3D=3D 2) > - { > - *cycles =3D 1; > + msp430_decode_operand (regs, as, ops_addr, ops, OP_16BIT, op1, comm1); > + msp430_decode_operand (regd, ad, opd_addr, opd, OP_16BIT, op2, comm2); >=20=20 > - if (regs =3D=3D 2) > - { > - sprintf (op1, "#4"); > - sprintf (comm1, "r2 As=3D=3D10"); > - } > - else if (regs =3D=3D 3) > - { > - sprintf (op1, "#2"); > - sprintf (comm1, "r3 As=3D=3D10"); > - } > - else > - { > - *cycles =3D 2; > + return cmd_len; > +} >=20=20 > - /* Indexed register mode @Rn. */ > - sprintf (op1, "@r%d", regs); > - } > - if (!regs) > - *cycles =3D 3; > - } > - else if (as =3D=3D 3) > - { > - if (regs =3D=3D 2) > - { > - sprintf (op1, "#8"); > - sprintf (comm1, "r2 As=3D=3D11"); > - *cycles =3D 1; > - } > - else if (regs =3D=3D 3) > - { > - sprintf (op1, "#-1"); > - sprintf (comm1, "r3 As=3D=3D11"); > - *cycles =3D 1; > - } > - else if (regs =3D=3D 0) > - { > - *cycles =3D 3; > - /* Absolute. @pc+. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op1, "#%d", dst); > - sprintf (comm1, "#0x%04x", PS (dst)); > - } > - else > - { > - *cycles =3D 2; > - sprintf (op1, "@r%d+", regs); > - } > - } > - else if (as =3D=3D 1) > - { > - if (regs =3D=3D 0) > - { > - *cycles =3D 4; > - /* PC relative. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op1, "0x%04x", PS (dst)); > - sprintf (comm1, "PC rel. 0x%04x", > - PS ((short) addr + 2 + dst)); > - } > - else if (regs =3D=3D 2) > - { > - *cycles =3D 2; > - /* Absolute. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op1, "&0x%04x", PS (dst)); > - sprintf (comm1, "0x%04x", PS (dst)); > - } > - else if (regs =3D=3D 3) > - { > - *cycles =3D 1; > - sprintf (op1, "#1"); > - sprintf (comm1, "r3 As=3D=3D01"); > - } > - else > - { > - *cycles =3D 3; > - /* Indexed. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op1, "%d(r%d)", dst, regs); > - } > - } > +static int > +msp430_branchinstr (disassemble_info * info, > + struct msp430_opcode_s const *opcode ATTRIBUTE_UNUSED, > + bfd_vma addr ATTRIBUTE_UNUSED, > + unsigned short insn, char *op1, char *comm1) > +{ > + int regs =3D (insn & 0x0f00) >> 8; > + int as =3D (insn & 0x0030) >> 4; > + int cmd_len =3D 2; > + bfd_vma op_addr; > + short dst; >=20=20 > - /* Destination. Special care needed on addr + XXXX. */ > + op_addr =3D addr + cmd_len; > + dst =3D msp430dis_operand (op_addr, info, regs, as, &cmd_len); > + msp430_decode_operand (regs, as, op_addr, dst, OP_16BIT_HEX, op1, comm= 1); >=20=20 > - if (ad =3D=3D 0) > - { > - /* Register. */ > - if (regd =3D=3D 0) > - { > - *cycles +=3D 1; > - sprintf (op2, "r0"); > - } > - else if (regd =3D=3D 1) > - sprintf (op2, "r1"); > + return cmd_len; > +} >=20=20 > - else if (regd =3D=3D 2) > - sprintf (op2, "r2"); > +static opwidth_t > +msp430x_opwidth (unsigned int insn) > +{ > + insn &=3D NON_ADDR_OPERATION | BYTE_OPERATION_X; > + > + if (insn =3D=3D (NON_ADDR_OPERATION | BYTE_OPERATION_X)) > + return BYTE_OP; > + if (insn =3D=3D NON_ADDR_OPERATION) > + return WORD_OP; > + if (insn =3D=3D BYTE_OPERATION_X) > + return ADDR_OP; > + /*NOTREACHED*/ return DEFAULT_OP; > +} >=20=20 > - else > - sprintf (op2, "r%d", regd); > - } > - else /* ad =3D=3D 1. */ > - { > - * cycles +=3D 3; > +static void > +set_repeats (unsigned int insn, int *repeats) > +{ > + if (0 =3D=3D (insn & 0x008f)) > + return; > + > + /* Use non-negative number to represent Rn; use a negative number to > + * represent an immediate count (note that the stored value is one > + * less than the count). */ > + if (insn & 0x0080) > + *repeats =3D insn & 0xf; > + else > + *repeats =3D -(1 + (insn & 0xf)); > +} >=20=20 > - if (regd =3D=3D 0) > - { > - /* PC relative. */ > - *cycles +=3D 1; > - dst =3D msp430dis_opcode (addr + cmd_len, info); > - sprintf (op2, "0x%04x", PS (dst)); > - sprintf (comm2, "PC rel. 0x%04x", > - PS ((short) addr + cmd_len + dst)); > - cmd_len +=3D 2; > - } > - else if (regd =3D=3D 2) > - { > - /* Absolute. */ > - dst =3D msp430dis_opcode (addr + cmd_len, info); > - cmd_len +=3D 2; > - sprintf (op2, "&0x%04x", PS (dst)); > - } > - else > - { > - dst =3D msp430dis_opcode (addr + cmd_len, info); > - cmd_len +=3D 2; > - sprintf (op2, "%d(r%d)", dst, regd); > - } > - } > +static int > +msp430x_singleoperand (disassemble_info * info, > + struct msp430_opcode_s const *opcode, > + bfd_vma addr, > + unsigned int insn, char *op, char *comm, int *repeats) > +{ > + int reg =3D (insn >> 16) & 0xf; > + int am =3D (insn >> 20) & 0x3; > + int cmd_len =3D 4; > + int dst =3D 0; > + bfd_vma op_addr; > + > + op_addr =3D addr + cmd_len; > + if (opcode_variant (opcode) < V_PUSHX) > + if ((am =3D=3D AMs_Immediate && reg =3D=3D REGNO_PC) /* #N */ > + || (am =3D=3D AM_Register && reg =3D=3D REGNO_CG2)) /* r3 */ > + { > + strcpy (comm, _("Illegal as 1-op instr")); > + return -1; > + } > + > + /* If register-mode extension set the repeat count */ > + if (am =3D=3D AM_Register) > + set_repeats (insn, repeats); > + > + dst =3D msp430dis_operand (op_addr, info, reg, am, > + &cmd_len) | ((insn & 0x0000000f) << 16); > + /* BOGOSITY: sign extension */ > + dst =3D (dst << 12) >> 12; > + msp430x_decode_operand (reg, am, op_addr, dst, OP_20BIT, op, comm); >=20=20 > return cmd_len; > } >=20=20 > static int > -msp430_branchinstr (disassemble_info *info, > - struct msp430_opcode_s *opcode ATTRIBUTE_UNUSED, > - bfd_vma addr ATTRIBUTE_UNUSED, > - unsigned short insn, > - char *op1, > - char *comm1, > - int *cycles) > +msp430x_exception (disassemble_info * info, > + struct msp430_opcode_s const *opcode, > + bfd_vma addr, > + unsigned int insn, > + char *op1, > + char *op2, char *comm1, char *comm2, opwidth_t * op_width) > { > - int regs =3D 0, regd =3D 0; > - int as =3D 0; > + int reg =3D 0; > int cmd_len =3D 2; > - short dst =3D 0; > + bfd_vma op_addr; > + int n =3D 0; > + int dst =3D 0; >=20=20 > - regd =3D insn & 0x0f; > - regs =3D (insn & 0x0f00) >> 8; > - as =3D (insn & 0x0030) >> 4; > - > - if (regd !=3D 0) /* Destination register is not a PC. */ > - return 0; > + reg =3D insn & 0xf; > + op_addr =3D addr + cmd_len; >=20=20 > - /* dst is a source register. */ > - if (as =3D=3D 0) > + switch (opcode_variant (opcode)) > { > - /* Constants. */ > - if (regs =3D=3D 3) > - { > - *cycles =3D 1; > - sprintf (op1, "#0"); > - sprintf (comm1, "r3 As=3D=3D00"); > - } > - else > - { > - /* Register. */ > - *cycles =3D 1; > - sprintf (op1, "r%d", regs); > + case V_CALLA: > + switch ((insn >> 4) & 0xf) > + { > + case 4: /* Rdst */ > + msp430x_decode_operand (reg, AM_Register, 0, 0, OP_OTHER, op1, comm1); > + break; > + case 5: /* x(Rdst) */ > + dst =3D msp430dis_operand (op_addr, info, reg, AM_Indexed, &cmd_len); > + msp430x_decode_operand (reg, AM_Indexed, op_addr, dst, > + OP_16BIT, op1, comm1); > + break; > + case 6: /* @Rdst */ > + msp430x_decode_operand (reg, AMs_IndirectRegister, 0, 0, OP_OTHER, op= 1, > + comm1); > + break; > + case 7: /* @Rdst+ */ > + msp430x_decode_operand (reg, AMs_IndirectAutoIncrement, 0, 0, OP_OTHE= R, > + op1, comm1); > + break; > + case 8: /* &abs20 */ > + dst =3D msp430dis_operand (op_addr, info, REGNO_CG1, AM_Indexed, &cmd= _len); > + dst |=3D (insn & 0x000f) << 16; > + msp430x_decode_operand (REGNO_CG1, AM_Symbolic, op_addr, > + dst, OP_20BIT_HEX, op1, comm1); > + break; > + case 9: /* EDE */ > + dst =3D msp430dis_operand (op_addr, info, REGNO_PC, AM_Indexed, &cmd_= len); > + dst |=3D (insn & 0x000f) << 16; > + msp430x_decode_operand (REGNO_PC, AM_Indexed, op_addr, dst, > + OP_20BIT, op1, comm1); > + break; > + case 0xb: /* #imm20 */ > + dst =3D msp430dis_operand (op_addr, info, REGNO_PC, AMs_Immediate, &c= md_len); > + dst |=3D (insn & 0x000f) << 16; > + msp430x_decode_operand (REGNO_PC, AMs_IndirectAutoIncrement, > + op_addr, dst, OP_20BIT_HEX, op1, comm1); > + break; > } > + break; > + case V_PUSHM: > + n =3D ((insn >> 4) & 0xf) + 1; > + msp430x_decode_operand (REGNO_PC, AMs_IndirectAutoIncrement, 0, n,= OP_DECIMAL, op1, comm1); /* #N */ > + msp430x_decode_operand (reg, AM_Register, 0, 0, OP_OTHER, op2, com= m2); /* Rdst */ > + if ((insn & 0x0100) =3D=3D 0) > + *op_width =3D ADDR_OP; > + break; > + case V_POPM: > + n =3D ((insn >> 4) & 0xf) + 1; > + reg =3D (reg + n - 1) & 0xf; > + msp430x_decode_operand (REGNO_PC, AMs_IndirectAutoIncrement, 0, n,= OP_DECIMAL, op1, comm1); /* #N */ > + msp430x_decode_operand (reg, AM_Register, 0, 0, OP_OTHER, op2, com= m2); /* Rdst */ > + if ((insn & 0x0100) =3D=3D 0) > + *op_width =3D ADDR_OP; > + break; > + case V_ROTM: > + n =3D ((insn >> 10) & 0x3) + 1; > + msp430x_decode_operand (REGNO_PC, AMs_IndirectAutoIncrement, 0, n,= OP_DECIMAL, op1, comm1); /* #N */ > + msp430x_decode_operand (reg, AM_Register, 0, 0, OP_OTHER, op2, com= m2); /* Rdst */ > + if ((insn & 0x0010) =3D=3D 0) > + *op_width =3D ADDR_OP; > + break; > + default: > + break; > } > - else if (as =3D=3D 2) > + return cmd_len; > +} > + > +static int > +msp430x_doubleoperand (disassemble_info * info, > + struct msp430_opcode_s const *opcode, > + bfd_vma addr, > + unsigned int insn, > + char *op1, > + char *op2, > + char *comm1, > + char *comm2, opwidth_t * op_width, int *repeats) > +{ > + int regs, regd; > + int as, ad; > + int ops, opd; > + int cmd_len =3D 4; > + bfd_vma ops_addr; > + bfd_vma opd_addr; > + > + regd =3D (insn >> 16) & 0xf; > + regs =3D (insn >> 24) & 0xf; > + as =3D (insn >> 20) & 0x3; > + ad =3D (insn >> 23) & 0x1; > + > + ops_addr =3D addr + cmd_len; > + > + if (ad =3D=3D AM_Register && regd =3D=3D REGNO_CG2) > { > - if (regs =3D=3D 2) > - { > - *cycles =3D 2; > - sprintf (op1, "#4"); > - sprintf (comm1, "r2 As=3D=3D10"); > - } > - else if (regs =3D=3D 3) > - { > - *cycles =3D 1; > - sprintf (op1, "#2"); > - sprintf (comm1, "r3 As=3D=3D10"); > - } > - else > - { > - /* Indexed register mode @Rn. */ > - *cycles =3D 2; > - sprintf (op1, "@r%d", regs); > - } > + /* R3 is illegal as dest: may be data section. */ > + if (comm1) > + strcpy (comm1, _("Illegal as 2-op instr")); > + else if (comm2) > + strcpy (comm2, _("Illegal as 2-op instr")); > + return -1; > } > - else if (as =3D=3D 3) > + *op_width =3D msp430x_opwidth (insn); > + > + /* If register-mode extension set the repeat count */ > + if (as =3D=3D AM_Register && ad =3D=3D AM_Register) > + set_repeats (insn, repeats); > + > + ops =3D msp430dis_operand (ops_addr, info, regs, as, &cmd_len); > + ops |=3D (insn & 0x00000780) << 9; > + /* BOGOSITY: sign extension */ > + ops =3D (ops << 12) >> 12; > + > + opd_addr =3D addr + cmd_len; > + opd =3D msp430dis_operand (opd_addr, info, regd, ad, &cmd_len); > + opd |=3D (insn & 0x0000000f) << 16; > + /* BOGOSITY: sign extension */ > + opd =3D (opd << 12) >> 12; > + > + msp430x_decode_operand (regs, as, ops_addr, ops, OP_20BIT, op1, comm1); > + > + if (opcode_variant (opcode) =3D=3D V_X_SHIFT && ((0 =3D=3D (as | ad) &= & ops !=3D opd) /* non-register extension different ops */ > + || regs !=3D regd)) /* register extension different regs */ > + return 0; > + > + msp430x_decode_operand (regd, ad, opd_addr, opd, OP_20BIT, op2, comm2); > + > + return cmd_len; > +} > + > +static int > +msp430x_address (disassemble_info * info, > + bfd_vma addr, > + unsigned short insn, > + char *op1, char *op2, char *comm1, char *comm2) > +{ > + int cmd_len =3D 2; > + bfd_vma op_addr; > + int dst =3D 0; > + typedef struct > + { > + int as, regs; > + int ad, regd; > + int length; > + } > + operands_t; > + > + static operands_t const operands_table[] =3D { > + {2, -1, 0, -1, 0}, /* 0 @Rsrc, Rdst */ > + {3, -1, 0, -1, 0}, /* 1 @Rsrc+, Rdst */ > + {1, 2, 0, -1, 2}, /* 2 &abs20, Rdst */ > + {1, -1, 0, -1, 2}, /* 3 x(Rsrc), Rdst */ > + {0, 0, 0, 0, 0}, /* 4 */ > + {0, 0, 0, 0, 0}, /* 5 */ > + {0, -1, 1, 2, 2}, /* 6 Rsrc, &abs20 */ > + {0, -1, 1, -1, 2}, /* 7 Rsrc, x(Rdst) */ > + {3, 0, 0, -1, 2}, /* 8 #imm20, Rdst */ > + {3, 0, 0, -1, 2}, /* 9 #imm20, Rdst */ > + {3, 0, 0, -1, 2}, /* a #imm20, Rdst */ > + {3, 0, 0, -1, 2}, /* b #imm20, Rdst */ > + {0, -1, 0, -1, 0}, /* c Rsrc, Rdst */ > + {0, -1, 0, -1, 0}, /* d Rsrc, Rdst */ > + {0, -1, 0, -1, 0}, /* e Rsrc, Rdst */ > + {0, -1, 0, -1, 0}, /* f Rsrc, Rdst */ > + }; > + operand_t size; > + > + op_addr =3D addr + cmd_len; > + operands_t operands =3D operands_table[(insn >> 4) & 0xf]; > + if (((insn >> 4) & 0xf) =3D=3D 6) > + dst =3D msp430dis_opcode (op_addr, info) | ((insn & 0x000f) << 16); > + else if (((insn >> 4) & 0xb) =3D=3D 3) > + dst =3D (short) msp430dis_opcode (op_addr, info); > + else if (operands.length !=3D 0) > + dst =3D msp430dis_opcode (op_addr, info) | ((insn & 0x0f00) << 8); > + > + if (operands.regs =3D=3D -1) > + operands.regs =3D (insn >> 8) & 0x000f; > + if (operands.regd =3D=3D -1) > + operands.regd =3D (insn >> 0) & 0x000f; > + > + if (operands.regd =3D=3D REGNO_CG2) > { > - if (regs =3D=3D 2) > - { > - *cycles =3D 1; > - sprintf (op1, "#8"); > - sprintf (comm1, "r2 As=3D=3D11"); > - } > - else if (regs =3D=3D 3) > - { > - *cycles =3D 1; > - sprintf (op1, "#-1"); > - sprintf (comm1, "r3 As=3D=3D11"); > - } > - else if (regs =3D=3D 0) > - { > - /* Absolute. @pc+ */ > - *cycles =3D 3; > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op1, "#0x%04x", PS (dst)); > - } > - else > - { > - *cycles =3D 2; > - sprintf (op1, "@r%d+", regs); > - } > + /* R3 is illegal as dest: may be data section. */ > + if (comm1) > + strcpy (comm1, _("Illegal as address instr")); > + else if (comm2) > + strcpy (comm2, _("Illegal as address instr")); > + return -1; > } > - else if (as =3D=3D 1) > - { > - * cycles =3D 3; > + /* 3 and 7 are used for 16-bit indexed offsets */ > + size =3D ((insn >> 4) & 0x0b) =3D=3D 3 ? OP_16BIT_HEX : OP_20BIT_HEX; > + msp430x_decode_operand (operands.regs, operands.as, op_addr, dst, > + size, op1, comm1); > + msp430x_decode_operand (operands.regd, operands.ad, op_addr, dst, > + size, op2, comm2); > + return cmd_len + operands.length; > +} >=20=20 > - if (regs =3D=3D 0) > - { > - /* PC relative. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - (*cycles)++; > - sprintf (op1, "0x%04x", PS (dst)); > - sprintf (comm1, "PC rel. 0x%04x", > - PS ((short) addr + 2 + dst)); > - } > - else if (regs =3D=3D 2) > - { > - /* Absolute. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op1, "&0x%04x", PS (dst)); > - } > - else if (regs =3D=3D 3) > - { > - (*cycles)--; > - sprintf (op1, "#1"); > - sprintf (comm1, "r3 As=3D=3D01"); > - } > - else > - { > - /* Indexd. */ > - dst =3D msp430dis_opcode (addr + 2, info); > - cmd_len +=3D 2; > - sprintf (op1, "%d(r%d)", dst, regs); > - } > +static int > +msp430x_emulated (disassemble_info * info, > + struct msp430_opcode_s const *opcode, > + bfd_vma addr, > + unsigned int insn, > + char *op1, char *comm1, opwidth_t * op_width, int *repeats) > +{ > + switch (opcode_variant (opcode)) > + { > + case V_NONE: > + case V_X_SHIFT: /* emulated by double operand instruction */ > + return msp430x_doubleoperand (info, opcode, addr, insn, (char *) 0= , op1, > + (char *) 0, comm1, op_width, repeats); > + case V_RETA: /* reta, substituted by mova */ > + return 2; > + case V_MOVA: > + case V_EMU_ADDR: /* substituted by other address instruction */ > + return msp430x_address (info, addr, insn, (char *) 0, op1, > + (char *) 0, comm1); > + case V_BRA: /* bra, substituted by mova */ > + return msp430x_address (info, addr, insn, op1, (char *) 0, > + comm1, (char *) 0); > + default: > + break; > } > - > - return cmd_len; > + return 0; > } >=20=20 > int > -print_insn_msp430 (bfd_vma addr, disassemble_info *info) > +print_insn_msp430 (bfd_vma addr, disassemble_info * info) > { > void *stream =3D info->stream; > fprintf_ftype prin =3D info->fprintf_func; > - struct msp430_opcode_s *opcode; > + struct msp430_opcode_s const *opcode; > char op1[32], op2[32], comm1[64], comm2[64]; > int cmd_len =3D 0; > - unsigned short insn; > - int cycles =3D 0; > - char *bc =3D ""; > - char dinfo[32]; /* Debug purposes. */ > + unsigned int insn; > + int repeats =3D 0; > + int cpu =3D > + (bfd_mach_msp430x =3D=3D info->mach) ? MSP430_CPU_MSP430X : MSP430_C= PU_MSP430; > + > + opwidth_t op_width =3D DEFAULT_OP; > + static char const *width_modifier[] =3D { "", "", ".b", ".a" }; >=20=20 > insn =3D msp430dis_opcode (addr, info); > - sprintf (dinfo, "0x%04x", insn); >=20=20 > - if (((int) addr & 0xffff) > 0xffdf) > - { > - (*prin) (stream, "interrupt service routine at 0x%04x", 0xffff & i= nsn); > - return 2; > - } > + /* Detect extension words */ > + if (cpu >=3D MSP430_CPU_MSP430X && ((insn & 0xf800) =3D=3D 0x1800)) > + insn |=3D msp430dis_opcode (addr + 2, info) << 16; >=20=20 > *comm1 =3D 0; > *comm2 =3D 0; >=20=20 > for (opcode =3D msp430_opcodes; opcode->name; opcode++) > { > - if ((insn & opcode->bin_mask) =3D=3D opcode->bin_opcode > - && opcode->bin_opcode !=3D 0x9300) > + if ((insn & opcode->bin_mask) =3D=3D opcode->bin_opcode) > { > *op1 =3D 0; > *op2 =3D 0; > *comm1 =3D 0; > *comm2 =3D 0; >=20=20 > - /* r0 as destination. Ad should be zero. */ > - if (opcode->insn_opnumb =3D=3D 3 && (insn & 0x000f) =3D=3D 0 > - && (0x0080 & insn) =3D=3D 0) > + /* unsupported instruction */ > + if (opcode_format (opcode) >=3D FMT_X && cpu < MSP430_CPU_MSP430X) > + break; > + > + /* r0 as destination. Ad should be zero. Rdst=3D0 and Ad=3D0 are enco= ded in opcode & opcode_mask */ > + if (opcode_format (opcode) =3D=3D FMT_EMULATED > + && opcode_variant (opcode) =3D=3D V_BR) > { > cmd_len =3D > - msp430_branchinstr (info, opcode, addr, insn, op1, comm1, > - &cycles); > + msp430_branchinstr (info, opcode, addr, insn, op1, comm1); > if (cmd_len) > break; > } > + if (opcode_format (opcode) < FMT_X) > + switch (opcode->insn_opnumb) > + { > + case 0: > + cmd_len =3D msp430_nooperands (opcode, addr, insn, comm1); > + break; > + case 2: > + cmd_len =3D > + msp430_doubleoperand (info, opcode, addr, insn, op1, op2, > + comm1, comm2); > + if (insn & BYTE_OPERATION) > + op_width =3D BYTE_OP; > + break; > + case 1: > + cmd_len =3D > + msp430_singleoperand (info, opcode, addr, insn, op1, comm1); > + if (insn & BYTE_OPERATION > + && opcode_format (opcode) !=3D FMT_JUMP) > + op_width =3D BYTE_OP; > + break; > + default: > + break; > + } > + else /* 430x instruction */ > + switch (opcode_format (opcode)) > + { > + case FMT_X_SINGLE_OPERAND: > + if (opcode_variant (opcode) =3D=3D V_SWPSXT /* swpbx, sxtx */ > + && (insn & (NON_ADDR_OPERATION | BYTE_OPERATION_X)) =3D=3D 0) /* .= a, special case */ > + insn ^=3D BYTE_OPERATION_X; /* make A/L, B/W as ordinary */ > + > + op_width =3D msp430x_opwidth (insn); > + > + if (opcode_variant (opcode) =3D=3D V_SWPSXT && op_width =3D=3D BYTE_OP= ) /* swpbx, sxtx */ > + strcpy (comm1, _("Illegal A/L, B/W bits setting")); > + > + cmd_len =3D > + msp430x_singleoperand (info, opcode, addr, insn, op1, comm1, > + &repeats); > + break; > + case FMT_X_EXCEPTION: > + cmd_len =3D > + msp430x_exception (info, opcode, addr, insn, op1, op2, > + comm1, comm2, &op_width); > + break; > + case FMT_X_DOUBLE_OPERAND: > + cmd_len =3D > + msp430x_doubleoperand (info, opcode, addr, insn, op1, op2, > + comm1, comm2, &op_width, &repeats); > + break; > + case FMT_X_EMULATED: > + cmd_len =3D msp430x_emulated (info, opcode, addr, insn, op1, > + comm1, &op_width, &repeats); > + break; >=20=20 > - switch (opcode->insn_opnumb) > - { > - case 0: > - cmd_len =3D msp430_nooperands (opcode, addr, insn, comm1, &cycles= ); > - break; > - case 2: > - cmd_len =3D > - msp430_doubleoperand (info, opcode, addr, insn, op1, op2, > - comm1, comm2, &cycles); > - if (insn & BYTE_OPERATION) > - bc =3D ".b"; > - break; > - case 1: > - cmd_len =3D > - msp430_singleoperand (info, opcode, addr, insn, op1, comm1, > - &cycles); > - if (insn & BYTE_OPERATION && opcode->fmt !=3D 3) > - bc =3D ".b"; > - break; > - default: > - break; > - } > + case FMT_X_ADDRESS: > + cmd_len =3D msp430x_address (info, addr, insn, op1, op2, > + comm1, comm2); > + break; > + default: > + break; > + } > } >=20=20 > if (cmd_len) > break; > } >=20=20 > - dinfo[5] =3D 0; > - > if (cmd_len < 1) > { > /* Unknown opcode, or invalid combination of operands. */ > - (*prin) (stream, ".word 0x%04x; ????", PS (insn)); > + (*prin) (stream, ".word 0x%04x; ????\t%s%s", MASK_16 (insn), comm1, > + comm2); > return 2; > } >=20=20 > - (*prin) (stream, "%s%s", opcode->name, bc); > + > + if (repeats) > + { > + if (repeats < 0) > + (*prin) (stream, ".rpt\t#%d\n\t\t\t\t", -repeats); > + else > + (*prin) (stream, ".rpt\tr%d\n\t\t\t\t", repeats); > + } > + > + (*prin) (stream, "%s%s", opcode->name, width_modifier[op_width]); >=20=20 > if (*op1) > (*prin) (stream, "\t%s", op1); > @@ -765,23 +847,11 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *= info) >=20=20 > if (*comm1 || *comm2) > (*prin) (stream, ";"); > - else if (cycles) > - { > - if (*op2) > - (*prin) (stream, ";"); > - else > - { > - if (strlen (op1) < 7) > - (*prin) (stream, ";"); > - else > - (*prin) (stream, "\t;"); > - } > - } > if (*comm1) > (*prin) (stream, "%s", comm1); > if (*comm1 && *comm2) > - (*prin) (stream, ","); > + (*prin) (stream, ", "); > if (*comm2) > - (*prin) (stream, " %s", comm2); > + (*prin) (stream, "%s", comm2); > return cmd_len; > } --=20 Randy Yates Digital Signal Labs http://www.digitalsignallabs.com