* archures.c: Add some more MSP430 machine numbers.

* config.bfd (msp430): Define targ_selvecs.
	* configure.in: Add bfd_elf32_msp430_ti_vec.
	* cpu-msp430.c: Add some more MSP430 machine numbers.
	* elf32-msp430.c Add support for MSP430X relocations.
	Add support for TI compiler generated relocations.
	Add support for sym_diff relocations.
	Add support for relaxing out of range short branches into long
	branches.
	Add support for MSP430 attribute section.
	* reloc.c: Add MSP430X relocations.
	* targets.c: Add bfd_elf32_msp430_ti_vec.
	* bfd-in2.h: Regenerate.
	* configure: Regenerate.
	* libbfd.h: Regenerate.

	* readelf.c: Add support for MSP430X architecture.

	* readelf.exp: Expect -wi test to fail for the MSP430.

	* config/tc-msp430.c: Add support for the MSP430X architecture.
	Add code to insert a NOP instruction after any instruction that
	might change the interrupt state.
	Add support for the LARGE memory model.
	Add code to initialise the .MSP430.attributes section.
	* config/tc-msp430.h: Add support for the MSP430X architecture.
	* doc/c-msp430.texi: Document the new -mL and -mN command line
	options.
	* NEWS: Mention support for the MSP430X architecture.

	* gas/all/gas.exp: Skip the DIFF1 test for the MSP430.
	Expect the FORWARD test to pass for the MSP430.
	Skip the REDEF tests for the MSP430.
	Expect the 930509A test to fail for the MSP430.
	* gas/all/sleb128-4.d: Skip for the MSP430.
	* gas/elf/elf.exp: Set target_machine to msp430 for the MSP430.
	Skip the EHOPT0 test for the MSP430.
	Skip the REDEF and EQU-RELOC tests for the MSP430.
	* gas/elf/section2.e-msp430: New file.
	* gas/lns/lns-big-delta.d: Remove expectation of 20-bit
	addresses.
	* gas/lns/lns.exp: Use alternate LNS COMMON test for the MSP430.
	* gas/msp430/msp430x.s: New test.
	* gas/msp430/msp430x.d: Expected disassembly.
	* gas/msp430/msp430.exp: Run new test.
	* gas/msp430/opcode.d: Update expected disassembly.

	* msp430.h: Add MSP430X relocs.
	Add some more MSP430 machine numbers.
	Add values used by .MSP430.attributes section.

	* msp430.h: Add patterns for MSP430X instructions.

	* Makefile.am: Add emsp430X.c
	* Makefine.in: Regenerate.
	* configure.tgt (msp430): Add msp430X emulation.
	* ldmain.c (multiple_definition): Only disable relaxation if it
	was enabled by the user.
	* ldmain.h (RELAXATION_ENABLED_BY_USER): New macro.
	* emulparams/msp430all.sh: Add support for MSP430X.
	* emultempl/generic.em: (before_parse): Enable relaxation for the
	MSP430.
	* scripttempl/msp430.sc: Reorganize sections.  Add .rodata
	section.
	* scripttempl/msp430_3.sc: Likewise.
	* NEWS: Mention support for MSP430X.

	* ld-elf/flags1.d: Expect this test to pass on the MSP430.
	* ld-elf/init-fini-arrays.d: Expect this test to fail on the
	MSP430.
	* ld-elf/merge.d: Expect this test to pass on the MSP430.
	* ld-elf/sec64k.exp: Skip these tests for the MSP430.
	* ld-gc/pr13683.d: Expect this test to fail on the MSP430.
	* ld-srec/srec.exp: Expect these tests to fail on the MSP430.
	* ld-undefined/undefined.exp: Expect the UNDEFINED LINE test to
	fail on the MSP430.

	* msp430-dis.c: Add support for MSP430X instructions.
This commit is contained in:
Nick Clifton 2013-05-02 21:06:15 +00:00
parent 4925cdd75b
commit 13761a1136
52 changed files with 4749 additions and 821 deletions

View File

@ -1,3 +1,21 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* archures.c: Add some more MSP430 machine numbers.
* config.bfd (msp430): Define targ_selvecs.
* configure.in: Add bfd_elf32_msp430_ti_vec.
* cpu-msp430.c: Add some more MSP430 machine numbers.
* elf32-msp430.c Add support for MSP430X relocations.
Add support for TI compiler generated relocations.
Add support for sym_diff relocations.
Add support for relaxing out of range short branches into long
branches.
Add support for MSP430 attribute section.
* reloc.c: Add MSP430X relocations.
* targets.c: Add bfd_elf32_msp430_ti_vec.
* bfd-in2.h: Regenerate.
* configure: Regenerate.
* libbfd.h: Regenerate.
2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
* config.bfd: Replace alpha*-*-linuxecoff* pattern with

View File

@ -1,7 +1,5 @@
/* BFD library support routines for architectures.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2012, 2013 Free Software Foundation, Inc.
Copyright 1990-2013 Free Software Foundation, Inc.
Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -437,7 +435,12 @@ DESCRIPTION
.#define bfd_mach_msp14 14
.#define bfd_mach_msp15 15
.#define bfd_mach_msp16 16
.#define bfd_mach_msp20 20
.#define bfd_mach_msp21 21
.#define bfd_mach_msp22 22
.#define bfd_mach_msp23 23
.#define bfd_mach_msp24 24
.#define bfd_mach_msp26 26
.#define bfd_mach_msp31 31
.#define bfd_mach_msp32 32
.#define bfd_mach_msp33 33
@ -445,6 +448,10 @@ DESCRIPTION
.#define bfd_mach_msp42 42
.#define bfd_mach_msp43 43
.#define bfd_mach_msp44 44
.#define bfd_mach_msp430x 45
.#define bfd_mach_msp46 46
.#define bfd_mach_msp47 47
.#define bfd_mach_msp54 54
. bfd_arch_xc16x, {* Infineon's XC16X Series. *}
.#define bfd_mach_xc16x 1
.#define bfd_mach_xc16xl 2

View File

@ -2170,7 +2170,12 @@ enum bfd_architecture
#define bfd_mach_msp14 14
#define bfd_mach_msp15 15
#define bfd_mach_msp16 16
#define bfd_mach_msp20 20
#define bfd_mach_msp21 21
#define bfd_mach_msp22 22
#define bfd_mach_msp23 23
#define bfd_mach_msp24 24
#define bfd_mach_msp26 26
#define bfd_mach_msp31 31
#define bfd_mach_msp32 32
#define bfd_mach_msp33 33
@ -2178,6 +2183,10 @@ enum bfd_architecture
#define bfd_mach_msp42 42
#define bfd_mach_msp43 43
#define bfd_mach_msp44 44
#define bfd_mach_msp430x 45
#define bfd_mach_msp46 46
#define bfd_mach_msp47 47
#define bfd_mach_msp54 54
bfd_arch_xc16x, /* Infineon's XC16X Series. */
#define bfd_mach_xc16x 1
#define bfd_mach_xc16xl 2
@ -4918,6 +4927,21 @@ a matching LO8XG part. */
BFD_RELOC_MSP430_16_BYTE,
BFD_RELOC_MSP430_2X_PCREL,
BFD_RELOC_MSP430_RL_PCREL,
BFD_RELOC_MSP430_ABS8,
BFD_RELOC_MSP430X_PCR20_EXT_SRC,
BFD_RELOC_MSP430X_PCR20_EXT_DST,
BFD_RELOC_MSP430X_PCR20_EXT_ODST,
BFD_RELOC_MSP430X_ABS20_EXT_SRC,
BFD_RELOC_MSP430X_ABS20_EXT_DST,
BFD_RELOC_MSP430X_ABS20_EXT_ODST,
BFD_RELOC_MSP430X_ABS20_ADR_SRC,
BFD_RELOC_MSP430X_ABS20_ADR_DST,
BFD_RELOC_MSP430X_PCR16,
BFD_RELOC_MSP430X_PCR20_CALL,
BFD_RELOC_MSP430X_ABS16,
BFD_RELOC_MSP430_ABS_HI16,
BFD_RELOC_MSP430_PREL31,
BFD_RELOC_MSP430_SYM_DIFF,
/* Relocations used by the Altera Nios II core. */
BFD_RELOC_NIOS2_S16,

View File

@ -1134,6 +1134,7 @@ case "${targ}" in
msp430-*-*)
targ_defvec=bfd_elf32_msp430_vec
targ_selvecs=bfd_elf32_msp430_ti_vec
;;
ns32k-pc532-mach* | ns32k-pc532-ux*)

1
bfd/configure vendored
View File

@ -15292,6 +15292,7 @@ do
bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
bfd_elf32_mt_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;;
bfd_elf32_msp430_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
bfd_elf32_msp430_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
bfd_elf32_nbigmips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_ntradbigmips_vec | bfd_elf32_ntradbigmips_freebsd_vec)

View File

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
dnl
dnl Copyright 2012 Free Software Foundation
dnl Copyright 2012-2013 Free Software Foundation
dnl
dnl This file is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
@ -789,6 +789,7 @@ do
bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
bfd_elf32_mt_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;;
bfd_elf32_msp430_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
bfd_elf32_msp430_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
bfd_elf32_nbigmips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_ntradbigmips_vec | bfd_elf32_ntradbigmips_freebsd_vec)

View File

@ -1,6 +1,5 @@
/* BFD library support routines for the MSP architecture.
Copyright (C) 2002, 2003, 2005, 2007, 2012
Free Software Foundation, Inc.
Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of BFD, the Binary File Descriptor library.
@ -82,29 +81,56 @@ static const bfd_arch_info_type arch_info_struct[] =
/* msp430x16x. */
N (16, bfd_mach_msp16, "msp:16", FALSE, & arch_info_struct[7]),
/* msp430x20x. */
N (16, bfd_mach_msp20, "msp:20", FALSE, & arch_info_struct[8]),
/* msp430x21x. */
N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[8]),
N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[9]),
/* msp430x22x. */
N (16, bfd_mach_msp22, "msp:22", FALSE, & arch_info_struct[10]),
/* msp430x23x. */
N (16, bfd_mach_msp23, "msp:23", FALSE, & arch_info_struct[11]),
/* msp430x24x. */
N (16, bfd_mach_msp24, "msp:24", FALSE, & arch_info_struct[12]),
/* msp430x26x. */
N (16, bfd_mach_msp26, "msp:26", FALSE, & arch_info_struct[13]),
/* msp430x31x. */
N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[9]),
N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[14]),
/* msp430x32x. */
N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[10]),
N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[15]),
/* msp430x33x. */
N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[11]),
N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[16]),
/* msp430x41x. */
N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[12]),
N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[17]),
/* msp430x42x. */
N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[13]),
N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[18]),
/* msp430x43x. */
N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[14]),
N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[19]),
/* msp430x44x. */
N (16, bfd_mach_msp43, "msp:44", FALSE, NULL)
N (16, bfd_mach_msp43, "msp:44", FALSE, & arch_info_struct[20]),
/* msp430x46x. */
N (16, bfd_mach_msp46, "msp:46", FALSE, & arch_info_struct[21]),
/* msp430x47x. */
N (16, bfd_mach_msp47, "msp:47", FALSE, & arch_info_struct[22]),
/* msp430x54x. */
N (16, bfd_mach_msp54, "msp:54", FALSE, & arch_info_struct[23]),
N (32, bfd_mach_msp430x, "msp:430X", FALSE, NULL)
};
const bfd_arch_info_type bfd_msp430_arch =

File diff suppressed because it is too large Load Diff

View File

@ -2376,6 +2376,21 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MSP430_16_BYTE",
"BFD_RELOC_MSP430_2X_PCREL",
"BFD_RELOC_MSP430_RL_PCREL",
"BFD_RELOC_MSP430_ABS8",
"BFD_RELOC_MSP430X_PCR20_EXT_SRC",
"BFD_RELOC_MSP430X_PCR20_EXT_DST",
"BFD_RELOC_MSP430X_PCR20_EXT_ODST",
"BFD_RELOC_MSP430X_ABS20_EXT_SRC",
"BFD_RELOC_MSP430X_ABS20_EXT_DST",
"BFD_RELOC_MSP430X_ABS20_EXT_ODST",
"BFD_RELOC_MSP430X_ABS20_ADR_SRC",
"BFD_RELOC_MSP430X_ABS20_ADR_DST",
"BFD_RELOC_MSP430X_PCR16",
"BFD_RELOC_MSP430X_PCR20_CALL",
"BFD_RELOC_MSP430X_ABS16",
"BFD_RELOC_MSP430_ABS_HI16",
"BFD_RELOC_MSP430_PREL31",
"BFD_RELOC_MSP430_SYM_DIFF",
"BFD_RELOC_NIOS2_S16",
"BFD_RELOC_NIOS2_U16",
"BFD_RELOC_NIOS2_CALL26",

View File

@ -5662,6 +5662,36 @@ ENUMX
BFD_RELOC_MSP430_2X_PCREL
ENUMX
BFD_RELOC_MSP430_RL_PCREL
ENUMX
BFD_RELOC_MSP430_ABS8
ENUMX
BFD_RELOC_MSP430X_PCR20_EXT_SRC
ENUMX
BFD_RELOC_MSP430X_PCR20_EXT_DST
ENUMX
BFD_RELOC_MSP430X_PCR20_EXT_ODST
ENUMX
BFD_RELOC_MSP430X_ABS20_EXT_SRC
ENUMX
BFD_RELOC_MSP430X_ABS20_EXT_DST
ENUMX
BFD_RELOC_MSP430X_ABS20_EXT_ODST
ENUMX
BFD_RELOC_MSP430X_ABS20_ADR_SRC
ENUMX
BFD_RELOC_MSP430X_ABS20_ADR_DST
ENUMX
BFD_RELOC_MSP430X_PCR16
ENUMX
BFD_RELOC_MSP430X_PCR20_CALL
ENUMX
BFD_RELOC_MSP430X_ABS16
ENUMX
BFD_RELOC_MSP430_ABS_HI16
ENUMX
BFD_RELOC_MSP430_PREL31
ENUMX
BFD_RELOC_MSP430_SYM_DIFF
ENUMDOC
msp430 specific relocation codes

View File

@ -1,7 +1,5 @@
/* Generic target-file-type support for the BFD library.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Copyright 1990-2013 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -668,6 +666,7 @@ extern const bfd_target bfd_elf32_mn10200_vec;
extern const bfd_target bfd_elf32_mn10300_vec;
extern const bfd_target bfd_elf32_mt_vec;
extern const bfd_target bfd_elf32_msp430_vec;
extern const bfd_target bfd_elf32_msp430_ti_vec;
extern const bfd_target bfd_elf32_nbigmips_vec;
extern const bfd_target bfd_elf32_nlittlemips_vec;
extern const bfd_target bfd_elf32_ntradbigmips_vec;
@ -1047,6 +1046,7 @@ static const bfd_target * const _bfd_target_vector[] =
&bfd_elf32_mn10300_vec,
&bfd_elf32_mt_vec,
&bfd_elf32_msp430_vec,
&bfd_elf32_msp430_ti_vec,
#ifdef BFD64
&bfd_elf32_nbigmips_vec,
&bfd_elf32_nlittlemips_vec,

View File

@ -131,6 +131,7 @@
#include "elf/moxie.h"
#include "elf/mt.h"
#include "elf/msp430.h"
#include "elf/nios2.h"
#include "elf/or32.h"
#include "elf/pj.h"
#include "elf/ppc.h"
@ -153,8 +154,6 @@
#include "elf/xstormy16.h"
#include "elf/xtensa.h"
#include "elf/nios2.h"
#include "getopt.h"
#include "libiberty.h"
#include "safe-ctype.h"
@ -903,6 +902,17 @@ get_reloc_symindex (bfd_vma reloc_info)
return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
}
static inline bfd_boolean
uses_msp430x_relocs (void)
{
return
elf_header.e_machine == EM_MSP430 /* Paranoia. */
/* GCC uses osabi == ELFOSBI_STANDALONE. */
&& (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
/* TI compiler uses ELFOSABI_NONE. */
|| (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
}
/* Display the contents of the relocation data found at the specified
offset. */
@ -1125,6 +1135,11 @@ dump_relocations (FILE * file,
break;
case EM_MSP430:
if (uses_msp430x_relocs ())
{
rtype = elf_msp430x_reloc_type (type);
break;
}
case EM_MSP430_OLD:
rtype = elf_msp430_reloc_type (type);
break;
@ -2781,6 +2796,32 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
if ((e_flags & EF_C6000_REL))
strcat (buf, ", relocatable module");
break;
case EM_MSP430:
strcat (buf, _(": architecture variant: "));
switch (e_flags & EF_MSP430_MACH)
{
case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
default:
strcat (buf, _(": unknown")); break;
}
if (e_flags & ~ EF_MSP430_MACH)
strcat (buf, _(": unknown extra flag bits also present"));
}
}
@ -3205,6 +3246,18 @@ get_tic6x_section_type_name (unsigned int sh_type)
return NULL;
}
static const char *
get_msp430x_section_type_name (unsigned int sh_type)
{
switch (sh_type)
{
case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
default: return NULL;
}
}
static const char *
get_section_type_name (unsigned int sh_type)
{
@ -3270,6 +3323,9 @@ get_section_type_name (unsigned int sh_type)
case EM_TI_C6000:
result = get_tic6x_section_type_name (sh_type);
break;
case EM_MSP430:
result = get_msp430x_section_type_name (sh_type);
break;
default:
result = NULL;
break;
@ -8994,8 +9050,13 @@ get_symbol_type (unsigned int type)
default:
if (type >= STT_LOPROC && type <= STT_HIPROC)
{
if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
return "THUMB_FUNC";
if (elf_header.e_machine == EM_ARM)
{
if (type == STT_ARM_TFUNC)
return "THUMB_FUNC";
if (type == STT_ARM_16BIT)
return "THUMB_LABEL";
}
if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
return "REGISTER";
@ -9961,6 +10022,60 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
switch (elf_header.e_machine)
{
case EM_MSP430:
case EM_MSP430_OLD:
{
static Elf_Internal_Sym * saved_sym = NULL;
switch (reloc_type)
{
case 10: /* R_MSP430_SYM_DIFF */
if (uses_msp430x_relocs ())
break;
case 21: /* R_MSP430X_SYM_DIFF */
saved_sym = symtab + get_reloc_symindex (reloc->r_info);
return TRUE;
case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
goto handle_sym_diff;
case 5: /* R_MSP430_16_BYTE */
case 9: /* R_MSP430_8 */
if (uses_msp430x_relocs ())
break;
goto handle_sym_diff;
case 2: /* R_MSP430_ABS16 */
case 15: /* R_MSP430X_ABS16 */
if (! uses_msp430x_relocs ())
break;
goto handle_sym_diff;
handle_sym_diff:
if (saved_sym != NULL)
{
bfd_vma value;
value = reloc->r_addend
+ (symtab[get_reloc_symindex (reloc->r_info)].st_value
- saved_sym->st_value);
byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
saved_sym = NULL;
return TRUE;
}
break;
default:
if (saved_sym != NULL)
error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
break;
}
break;
}
case EM_MN10300:
case EM_CYGNUS_MN10300:
{
@ -10100,7 +10215,7 @@ is_32bit_abs_reloc (unsigned int reloc_type)
return reloc_type == 1; /* R_MOXIE_32. */
case EM_MSP430_OLD:
case EM_MSP430:
return reloc_type == 1; /* R_MSP43_32. */
return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
case EM_MT:
return reloc_type == 2; /* R_MT_32. */
case EM_ALTERA_NIOS2:
@ -10352,6 +10467,8 @@ is_16bit_abs_reloc (unsigned int reloc_type)
case EM_M32C:
return reloc_type == 1; /* R_M32C_16 */
case EM_MSP430:
if (uses_msp430x_relocs ())
return reloc_type == 2; /* R_MSP430_ABS16. */
case EM_MSP430_OLD:
return reloc_type == 5; /* R_MSP430_16_BYTE. */
case EM_ALTERA_NIOS2:
@ -11905,6 +12022,79 @@ display_raw_attribute (unsigned char * p, unsigned char * end)
putchar ('\n');
}
static unsigned char *
display_msp430x_attribute (unsigned char * p,
const unsigned char * const end)
{
unsigned int len;
int val;
int tag;
tag = read_uleb128 (p, & len, end);
p += len;
switch (tag)
{
case OFBA_MSPABI_Tag_ISA:
val = read_uleb128 (p, &len, end);
p += len;
printf (" Tag_ISA: ");
switch (val)
{
case 0: printf (_("None\n")); break;
case 1: printf (_("MSP430\n")); break;
case 2: printf (_("MSP430X\n")); break;
default: printf ("??? (%d)\n", val); break;
}
break;
case OFBA_MSPABI_Tag_Code_Model:
val = read_uleb128 (p, &len, end);
p += len;
printf (" Tag_Code_Model: ");
switch (val)
{
case 0: printf (_("None\n")); break;
case 1: printf (_("Small\n")); break;
case 2: printf (_("Large\n")); break;
default: printf ("??? (%d)\n", val); break;
}
break;
case OFBA_MSPABI_Tag_Data_Model:
val = read_uleb128 (p, &len, end);
p += len;
printf (" Tag_Data_Model: ");
switch (val)
{
case 0: printf (_("None\n")); break;
case 1: printf (_("Small\n")); break;
case 2: printf (_("Large\n")); break;
case 3: printf (_("Restricted Large\n")); break;
default: printf ("??? (%d)\n", val); break;
}
break;
default:
printf (_(" <unknown tag %d>: "), tag);
if (tag & 1)
{
printf ("\"%s\"\n", p);
p += strlen ((char *) p) + 1;
}
else
{
val = read_uleb128 (p, &len, end);
p += len;
printf ("%d (0x%x)\n", val, val);
}
break;
}
return p;
}
static int
process_attributes (FILE * file,
const char * public_name,
@ -12076,6 +12266,13 @@ process_tic6x_specific (FILE * file)
display_tic6x_attribute, NULL);
}
static int
process_msp430x_specific (FILE * file)
{
return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
display_msp430x_attribute, NULL);
}
/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
Print the Address, Access and Initial fields of an entry at VMA ADDR
and return the VMA of the next entry. */
@ -13554,6 +13751,8 @@ process_arch_specific (FILE * file)
case EM_TI_C6000:
return process_tic6x_specific (file);
break;
case EM_MSP430:
return process_msp430x_specific (file);
default:
break;
}

View File

@ -1,3 +1,7 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* readelf.exp: Expect -wi test to fail for the MSP430.
2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
* lib/binutils-common.exp (is_elf_format): Also exclude

View File

@ -1,5 +1,4 @@
# Copyright 1999, 2000, 2001, 2003, 2004, 2007, 2009, 2012
# Free Software Foundation, Inc.
# Copyright 1999-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -196,6 +195,9 @@ proc readelf_wi_test {} {
".*\(DW_OP_addr: 0\).*"
}
# The MSP430 in LARGE mode does not generate a DW_OP_addr.
setup_xfail msp430*-*-*
foreach looked_for $sought {
set lines [grep $output $looked_for]
if ![llength $lines] then {

View File

@ -1,3 +1,15 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* config/tc-msp430.c: Add support for the MSP430X architecture.
Add code to insert a NOP instruction after any instruction that
might change the interrupt state.
Add support for the LARGE memory model.
Add code to initialise the .MSP430.attributes section.
* config/tc-msp430.h: Add support for the MSP430X architecture.
* doc/c-msp430.texi: Document the new -mL and -mN command line
options.
* NEWS: Mention support for the MSP430X architecture.
2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
* configure.tgt: Replace alpha*-*-linuxecoff* pattern with

View File

@ -1,5 +1,7 @@
-*- text -*-
* Add support for the Texas Instruments MSP430X processor.
* Add -gdwarf-sections command line option to enable per-code-section
generation of DWARF .debug_line sections.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* This file is tc-msp430.h
Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
@ -99,8 +99,9 @@ extern long md_pcrel_from_section (struct fix *, segT);
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 */
/* Support symbols like: C$$IO$$. */
#undef LEX_DOLLAR
#define LEX_DOLLAR 1
#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) = 0
/* An `.lcomm' directive with no explicit alignment parameter will
@ -116,9 +117,52 @@ extern long md_pcrel_from_section (struct fix *, segT);
extern long msp430_relax_frag (segT, fragS *, long);
#define TC_FORCE_RELOCATION_LOCAL(FIX) \
msp430_force_relocation_local(FIX)
extern int msp430_force_relocation_local(struct fix *);
msp430_force_relocation_local (FIX)
extern int msp430_force_relocation_local (struct fix *);
extern int msp430_enable_relax;
extern int msp430_enable_polys;
#define tc_fix_adjustable(FIX) msp430_fix_adjustable (FIX)
extern bfd_boolean msp430_fix_adjustable (struct fix *);
/* Allow hexadeciaml numbers with 'h' suffix. Note that if the number
starts with a letter it will be interpreted as a symbol name not a
constant. Thus "beach" is a symbol not the hex value 0xbeac. So
is A5A5h... */
#define NUMBERS_WITH_SUFFIX 1
#define md_end msp430_md_end
extern void msp430_md_end (void);
/* Do not allow call frame debug info optimization as otherwise we could
generate the DWARF directives without the relocs necessary to patch
them up. */
#define md_allow_eh_opt 0
/* The difference between same-section symbols may be affected by linker
relaxation, so do not resolve such expressions in the assembler. */
#define md_allow_local_subtract(l,r,s) msp430_allow_local_subtract (l, r, s)
extern bfd_boolean msp430_allow_local_subtract (expressionS *, expressionS *, segT);
#define RELOC_EXPANSION_POSSIBLE
#define MAX_RELOC_EXPANSION 2
#define DIFF_EXPR_OK
/* Do not adjust relocations involving symbols in code sections,
because it breaks linker relaxations. This could be fixed in the
linker, but this fix is simpler, and it pretty much only affects
object size a little bit. */
#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
(((SEC)->flags & SEC_CODE) != 0 \
|| ! SEG_NORMAL (SEC) \
|| TC_FORCE_RELOCATION (FIX))
/* We validate subtract arguments within tc_gen_reloc(),
so don't report errors at this point. */
#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1
#define DWARF2_USE_FIXED_ADVANCE_PC 1
#define TC_LINKRELAX_FIXUP(seg) (seg->flags & SEC_CODE)

View File

@ -1,4 +1,4 @@
@c Copyright 2002, 2004, 2005, 2011 Free Software Foundation, Inc.
@c Copyright 2002-2013 Free Software Foundation, Inc.
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@ifset GENERIC
@ -36,6 +36,20 @@ enables polymorph instructions handler.
@item -mQ
enables relaxation at assembly time. DANGEROUS!
@item -ml
indicates that the input uses the large code model.
@item -mN
disables the generation of a NOP instruction following any instruction
that might change the interrupts enabled/disabled state. For the
MSP430x5xx series the instructions: @code{EINT}, @code{DINT}, @code{BIC
#8, SR}, @code{BIS #8, SR} and @code{MOV.W <>, SR} must be followed by
a NOP instruction in order to ensure the correct processing of
interrupts. By default generation of the NOP instruction happens
automatically, but this command line option disables this behaviour.
It is then up to the programmer to ensure that interrupts are enabled
and disabled correctly.
@end table
@node MSP430 Syntax

View File

@ -1,3 +1,22 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* gas/all/gas.exp: Skip the DIFF1 test for the MSP430.
Expect the FORWARD test to pass for the MSP430.
Skip the REDEF tests for the MSP430.
Expect the 930509A test to fail for the MSP430.
* gas/all/sleb128-4.d: Skip for the MSP430.
* gas/elf/elf.exp: Set target_machine to msp430 for the MSP430.
Skip the EHOPT0 test for the MSP430.
Skip the REDEF and EQU-RELOC tests for the MSP430.
* gas/elf/section2.e-msp430: New file.
* gas/lns/lns-big-delta.d: Remove expectation of 20-bit
addresses.
* gas/lns/lns.exp: Use alternate LNS COMMON test for the MSP430.
* gas/msp430/msp430x.s: New test.
* gas/msp430/msp430x.d: Expected disassembly.
* gas/msp430/msp430.exp: Run new test.
* gas/msp430/opcode.d: Update expected disassembly.
2013-04-30 Chao-ying Fu <Chao-ying.Fu@imgtec.com>
* gas/mips/ext-ill.s: New file.

View File

@ -61,6 +61,7 @@ if { ![istarget hppa*-*-*]
&& ![istarget alpha*-*-*vms*]
&& ![istarget rx-*-*]
&& ![istarget mn10300-*-*]
&& ![istarget msp430*-*-*]
&& ![istarget am3*-*-*] } then {
gas_test_error "diff1.s" "" "difference of two undefined symbols"
}
@ -99,7 +100,7 @@ case $target_triplet in {
default {
# Some targets don't manage to resolve BFD_RELOC_8 for constants.
setup_xfail "alpha*-*-*" "*c30*-*-*" "*c4x*-*-*" \
"d\[13\]0v*-*-*" "i860-*-*" "mips*-*-*" "msp430-*-*" \
"d\[13\]0v*-*-*" "i860-*-*" "mips*-*-*" \
"pdp11-*-*" "xtensa*-*-*"
run_dump_test forward
}
@ -139,6 +140,7 @@ case $target_triplet in {
{ mips*-*-* } { }
{ mn10200-*-* } { }
{ mn10300-*-* } { }
{ msp430*-*-* } { }
{ pdp11-*-* } { }
{ tic30*-*-* } { }
{ tic4x*-*-* } { }
@ -266,8 +268,8 @@ if { ![istarget hppa*-*-*] &&
![istarget *c54x*-*-*] } then {
# the vax fails because VMS can apparently actually handle this
# case in relocs, so gas doesn't handle it itself.
# mn10300 emits two relocs to handle the difference of two symbols.
setup_xfail "mn10300*-*-*" "vax*-*-vms*"
# msp430 and mn10300 emit two relocs to handle the difference of two symbols.
setup_xfail "mn10300*-*-*" "msp430*-*-*" "vax*-*-vms*"
do_930509a
}

View File

@ -1,5 +1,6 @@
#objdump : -s -j .data -j "\$DATA\$"
#name : .sleb128 tests (4)
#skip: msp430*-*-*
.*: .*

View File

@ -1,5 +1,4 @@
# Copyright 2012
# Free Software Foundation, Inc.
# Copyright 2012-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -62,6 +61,9 @@ if { [is_elf_format] } then {
if {[istarget m32r*-*-*]} then {
set target_machine -m32r
}
if {[istarget "msp430-*-*"]} then {
set target_machine -msp430
}
if {[istarget "score-*-*"]} then {
set target_machine -score
}
@ -91,6 +93,7 @@ if { [is_elf_format] } then {
# function prologues.
if {![istarget "mn10300-*-*"]
&& ![istarget "xtensa*-*-*"]
&& ![istarget "msp430*-*-*"]
&& ![istarget "am3*-*-*"]} then {
run_dump_test "ehopt0"
}
@ -136,6 +139,7 @@ if { [is_elf_format] } then {
{ mips*-*-* } { }
{ mn10200-*-* } { }
{ mn10300-*-* } { }
{ msp43*-*-* } { }
{ *c54x*-*-* } { }
{ rx-*-* } { }
default {

View File

@ -10,8 +10,8 @@ Raw dump of debug contents of section \.debug_line:
Advance PC by fixed size amount 0 to 0x0
Copy
Advance Line by 1 to 3
Extended opcode 2: set Address to 0x.....
Extended opcode 2: set Address to 0x.*
Copy
Advance PC by fixed size amount . to 0x.....
Advance PC by fixed size amount . to 0x.*
Extended opcode 1: End of Sequence
#pass

View File

@ -38,6 +38,7 @@ if {
|| [istarget am3*-*-*]
|| [istarget cr16-*-*]
|| [istarget crx-*-*]
|| [istarget msp430-*-*]
|| [istarget mn10*-*-*] } {
run_dump_test "lns-common-1-alt"
run_dump_test "lns-big-delta"

View File

@ -1,5 +1,4 @@
# Copyright 2012
# Free Software Foundation, Inc.
# Copyright 2012-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -21,4 +20,5 @@
if [expr [istarget "msp430-*-*"]] then {
run_dump_test "opcode"
run_dump_test "msp430x"
}

View File

@ -22,14 +22,14 @@ Disassembly of section .text:
0+024 <[^>]*> 8c 10 swpb r12 ;
0+026 <[^>]*> 0d 10 rrc r13 ;
0+028 <[^>]*> 30 41 ret
0+02a <[^>]*> 31 40 00 00 mov #0, r1 ;#0x0000
0+02e <[^>]*> b0 12 00 00 call #0 ;#0x0000
0+02a <[^>]*> 31 40 00 00 mov #0, r1 ;
0+02e <[^>]*> b0 12 00 00 call #0 ;
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+03e <[^>]*> b0 12 00 00 call #0 ;
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
@ -37,7 +37,7 @@ Disassembly of section .text:
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+056 <[^>]*> b0 12 00 00 call #0 ;
0+05a <[^>]*> 82 4e 00 00 mov r14, &0x0000 ;
0+05e <[^>]*> 82 4f 00 00 mov r15, &0x0000 ;
0+062 <[^>]*> 3f 40 f0 00 mov #240, r15 ;#0x00f0

View File

@ -1,3 +1,9 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* msp430.h: Add MSP430X relocs.
Add some more MSP430 machine numbers.
Add values used by .MSP430.attributes section.
2013-03-21 Michael Schewe <michael.schewe@gmx.net>
* h8.h: Add new reloc R_H8_DISP32A16 for relaxation of

View File

@ -1,5 +1,5 @@
/* MSP430 ELF support for BFD.
Copyright (C) 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of BFD, the Binary File Descriptor library.
@ -33,6 +33,11 @@
#define E_MSP430_MACH_MSP430x14 14
#define E_MSP430_MACH_MSP430x15 15
#define E_MSP430_MACH_MSP430x16 16
#define E_MSP430_MACH_MSP430x20 20
#define E_MSP430_MACH_MSP430x22 22
#define E_MSP430_MACH_MSP430x23 23
#define E_MSP430_MACH_MSP430x24 24
#define E_MSP430_MACH_MSP430x26 26
#define E_MSP430_MACH_MSP430x31 31
#define E_MSP430_MACH_MSP430x32 32
#define E_MSP430_MACH_MSP430x33 33
@ -40,6 +45,19 @@
#define E_MSP430_MACH_MSP430x42 42
#define E_MSP430_MACH_MSP430x43 43
#define E_MSP430_MACH_MSP430x44 44
#define E_MSP430_MACH_MSP430X 45
#define E_MSP430_MACH_MSP430x46 46
#define E_MSP430_MACH_MSP430x47 47
#define E_MSP430_MACH_MSP430x54 54
#define SHT_MSP430_ATTRIBUTES 0x70000003 /* Section holds ABI attributes. */
#define SHT_MSP430_SEC_FLAGS 0x7f000005 /* Holds TI compiler's section flags. */
#define SHT_MSP430_SYM_ALIASES 0x7f000006 /* Holds TI compiler's symbol aliases. */
/* Tag values for an attribute section. */
#define OFBA_MSPABI_Tag_ISA 4
#define OFBA_MSPABI_Tag_Code_Model 6
#define OFBA_MSPABI_Tag_Data_Model 8
/* Relocations. */
START_RELOC_NUMBERS (elf_msp430_reloc_type)
@ -52,7 +70,32 @@ START_RELOC_NUMBERS (elf_msp430_reloc_type)
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_8, 9)
RELOC_NUMBER (R_MSP430_SYM_DIFF, 10)
END_RELOC_NUMBERS (R_MSP430_max)
START_RELOC_NUMBERS (elf_msp430x_reloc_type)
RELOC_NUMBER (R_MSP430_ABS32, 1) /* aka R_MSP430_32 */
RELOC_NUMBER (R_MSP430_ABS16, 2) /* aka R_MSP430_16 */
RELOC_NUMBER (R_MSP430_ABS8, 3)
RELOC_NUMBER (R_MSP430_PCR16, 4) /* aka R_MSP430_16_PCREL */
RELOC_NUMBER (R_MSP430X_PCR20_EXT_SRC, 5)
RELOC_NUMBER (R_MSP430X_PCR20_EXT_DST, 6)
RELOC_NUMBER (R_MSP430X_PCR20_EXT_ODST, 7)
RELOC_NUMBER (R_MSP430X_ABS20_EXT_SRC, 8)
RELOC_NUMBER (R_MSP430X_ABS20_EXT_DST, 9)
RELOC_NUMBER (R_MSP430X_ABS20_EXT_ODST, 10)
RELOC_NUMBER (R_MSP430X_ABS20_ADR_SRC, 11)
RELOC_NUMBER (R_MSP430X_ABS20_ADR_DST, 12)
RELOC_NUMBER (R_MSP430X_PCR16, 13) /* Like R_MSP430_PCR16 but with overflow checking. */
RELOC_NUMBER (R_MSP430X_PCR20_CALL, 14)
RELOC_NUMBER (R_MSP430X_ABS16, 15) /* Like R_MSP430_ABS16 but with overflow checking. */
RELOC_NUMBER (R_MSP430_ABS_HI16, 16)
RELOC_NUMBER (R_MSP430_PREL31, 17)
RELOC_NUMBER (R_MSP430_EHTYPE, 18) /* Mentioned in ABI. */
RELOC_NUMBER (R_MSP430X_10_PCREL, 19) /* Red Hat invention. Used for Jump instructions. */
RELOC_NUMBER (R_MSP430X_2X_PCREL, 20) /* Red Hat invention. Used for relaxing jumps. */
RELOC_NUMBER (R_MSP430X_SYM_DIFF, 21) /* Red Hat invention. Used for relaxing debug info. */
END_RELOC_NUMBERS (R_MSP430x_max)
#endif /* _ELF_MSP430_H */

View File

@ -1,3 +1,7 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* msp430.h: Add patterns for MSP430X instructions.
2013-04-06 David S. Miller <davem@davemloft.net>
* sparc.h (F_PREFERRED): Define.

View File

@ -1,6 +1,6 @@
/* Opcode table for the TI MSP430 microcontrollers
Copyright 2002, 2004, 2010 Free Software Foundation, Inc.
Copyright 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This program is free software; you can redistribute it and/or modify
@ -119,6 +119,74 @@ static struct msp430_opcode_s msp430_opcodes[] =
MSP_INSN (bleu, 5, 2, 0, 0xffff),
MSP_INSN (ble, 5, 3, 0, 0xffff),
/* MSP430X instructions - these ones use an extension word.
A negative format indicates an MSP430X instruction. */
MSP_INSN (addcx, -2, 2, 0x6000, 0xf000),
MSP_INSN (addx, -2, 2, 0x5000, 0xf000),
MSP_INSN (andx, -2, 2, 0xf000, 0xf000),
MSP_INSN (bicx, -2, 2, 0xc000, 0xf000),
MSP_INSN (bisx, -2, 2, 0xd000, 0xf000),
MSP_INSN (bitx, -2, 2, 0xb000, 0xf000),
MSP_INSN (cmpx, -2, 2, 0x9000, 0xf000),
MSP_INSN (daddx, -2, 2, 0xa000, 0xf000),
MSP_INSN (movx, -2, 2, 0x4000, 0xf000),
MSP_INSN (subcx, -2, 2, 0x7000, 0xf000),
MSP_INSN (subx, -2, 2, 0x8000, 0xf000),
MSP_INSN (xorx, -2, 2, 0xe000, 0xf000),
/* MSP430X Synthetic instructions. */
MSP_INSN (adcx, -1, 1, 0x6300, 0xff30),
MSP_INSN (clra, -1, 1, 0x4300, 0xff30),
MSP_INSN (clrx, -1, 1, 0x4300, 0xff30),
MSP_INSN (dadcx, -1, 1, 0xa300, 0xff30),
MSP_INSN (decx, -1, 1, 0x8310, 0xff30),
MSP_INSN (decda, -1, 1, 0x8320, 0xff30),
MSP_INSN (decdx, -1, 1, 0x8320, 0xff30),
MSP_INSN (incx, -1, 1, 0x5310, 0xff30),
MSP_INSN (incda, -1, 1, 0x5320, 0xff30),
MSP_INSN (incdx, -1, 1, 0x5320, 0xff30),
MSP_INSN (invx, -1, 1, 0xe330, 0xfff0),
MSP_INSN (popx, -1, 1, 0x4130, 0xff30),
MSP_INSN (rlax, -1, 2, 0x5000, 0xf000),
MSP_INSN (rlcx, -1, 2, 0x6000, 0xf000),
MSP_INSN (sbcx, -1, 1, 0x7300, 0xff30),
MSP_INSN (tsta, -1, 1, 0x9300, 0xff30),
MSP_INSN (tstx, -1, 1, 0x9300, 0xff30),
MSP_INSN (pushx, -3, 1, 0x1200, 0xff80),
MSP_INSN (rrax, -3, 1, 0x1100, 0xff80),
MSP_INSN (rrcx, -3, 1, 0x1000, 0xff80),
MSP_INSN (swpbx, -3, 1, 0x1080, 0xffc0),
MSP_INSN (sxtx, -3, 1, 0x1180, 0xffc0),
/* MSP430X Address instructions - no extension word needed.
The insn_opnumb field is used to encode the nature of the
instruction for assembly and disassembly purposes. */
MSP_INSN (calla, -1, 4, 0x1300, 0xff00),
MSP_INSN (popm, -1, 5, 0x1600, 0xfe00),
MSP_INSN (pushm, -1, 5, 0x1400, 0xfe00),
MSP_INSN (rrcm, -1, 6, 0x0040, 0xf3e0),
MSP_INSN (rram, -1, 6, 0x0140, 0xf3e0),
MSP_INSN (rlam, -1, 6, 0x0240, 0xf3e0),
MSP_INSN (rrum, -1, 6, 0x0340, 0xf3e0),
MSP_INSN (rrux, -1, 7, 0x0340, 0xffe0), /* Synthesized in terms of RRUM. */
MSP_INSN (adda, -1, 8, 0x00a0, 0xf0b0),
MSP_INSN (cmpa, -1, 8, 0x0090, 0xf0b0),
MSP_INSN (suba, -1, 8, 0x00b0, 0xf0b0),
MSP_INSN (reta, -1, 9, 0x0110, 0xffff),
MSP_INSN (bra, -1, 9, 0x0000, 0xf0cf),
MSP_INSN (mova, -1, 9, 0x0000, 0xf080),
MSP_INSN (mova, -1, 9, 0x0080, 0xf0b0),
MSP_INSN (mova, -1, 9, 0x00c0, 0xf0f0),
/* Pseudo instruction to set the repeat field in the extension word. */
MSP_INSN (rpt, -1, 10, 0x0000, 0x0000),
/* End of instruction set. */
{ NULL, 0, 0, 0, 0 }
};

View File

@ -1,3 +1,19 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* Makefile.am: Add emsp430X.c
* Makefine.in: Regenerate.
* configure.tgt (msp430): Add msp430X emulation.
* ldmain.c (multiple_definition): Only disable relaxation if it
was enabled by the user.
* ldmain.h (RELAXATION_ENABLED_BY_USER): New macro.
* emulparams/msp430all.sh: Add support for MSP430X.
* emultempl/generic.em: (before_parse): Enable relaxation for the
MSP430.
* scripttempl/msp430.sc: Reorganize sections. Add .rodata
section.
* scripttempl/msp430_3.sc: Likewise.
* NEWS: Mention support for MSP430X.
2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
* configure.tgt: Replace alpha*-*-linuxecoff* pattern with

View File

@ -424,6 +424,7 @@ ALL_EMULATION_SOURCES = \
emsp430xW423.c \
emsp430xW425.c \
emsp430xW427.c \
emsp430X.c \
enews.c \
ens32knbsd.c \
eor32.c \
@ -1773,6 +1774,10 @@ emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
${GEN_DEPENDS}
${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
emsp430X.c: $(srcdir)/emulparams/msp430all.sh \
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
${GEN_DEPENDS}
${GENSCRIPTS} msp430X "$(tdir_msp430X)" msp430all
enews.c: $(srcdir)/emulparams/news.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} news "$(tdir_news)"

View File

@ -732,6 +732,7 @@ ALL_EMULATION_SOURCES = \
emsp430xW423.c \
emsp430xW425.c \
emsp430xW427.c \
emsp430X.c \
enews.c \
ens32knbsd.c \
eor32.c \
@ -1343,6 +1344,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)/emsp430X.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x110.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1101.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1111.Po@am__quote@
@ -3259,6 +3261,10 @@ emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
${GEN_DEPENDS}
${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
emsp430X.c: $(srcdir)/emulparams/msp430all.sh \
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
${GEN_DEPENDS}
${GENSCRIPTS} msp430X "$(tdir_msp430X)" msp430all
enews.c: $(srcdir)/emulparams/news.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} news "$(tdir_news)"

View File

@ -1,5 +1,7 @@
-*- text -*-
* Add support for the Texas Instruments MSP430X processor.
* Add support for Altera Nios II.
* Add support for the V850E3V5 architecture.

View File

@ -519,7 +519,7 @@ mn10300-*-*) targ_emul=mn10300
mt-*elf) targ_emul=elf32mt
;;
msp430-*-*) targ_emul=msp430x110
targ_extra_emuls="msp430x112 msp430x1101 msp430x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x1222 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp430x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 msp430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 msp430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp430xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x437 msp430x447 msp430x448 msp430x449"
targ_extra_emuls="msp430x112 msp430x1101 msp430x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x1222 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp430x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 msp430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 msp430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp430xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x437 msp430x447 msp430x448 msp430x449 msp430X"
;;
nios2*-*-*) targ_emul=nios2elf ;;
ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;;

View File

@ -551,3 +551,12 @@ RAM_START=0x0200
RAM_SIZE=0x400
STACK=0x600
fi
if [ "${MSP430_NAME}" = "msp430X" ] ; then
ARCH=msp:43
ROM_START=0x02000
ROM_SIZE=0x0dfe0
RAM_START=0x10000
RAM_SIZE=0x30000
STACK=0x600
fi

View File

@ -57,6 +57,18 @@ gld${EMULATION_NAME}_before_parse (void)
#ifndef TARGET_ /* I.e., if not generic. */
ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
#endif /* not TARGET_ */
EOF
# The MSP430 port *needs* linker relaxtion in order to cope with large
# functions where conditional branches do not fit into a +/- 1024 byte range.
case ${target} in
msp430-*-* )
fragment <<EOF
if (! link_info.relocatable)
TARGET_ENABLE_RELAXATION;
EOF
;;
esac
fragment <<EOF
}
EOF

View File

@ -1,7 +1,5 @@
/* Main program of GNU linker.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Copyright 1991-2013 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of the GNU Binutils.
@ -953,10 +951,10 @@ multiple_definition (struct bfd_link_info *info,
if (obfd != NULL)
einfo (_("%D: first defined here\n"), obfd, osec, oval);
if (RELAXATION_ENABLED)
if (RELAXATION_ENABLED_BY_USER)
{
einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n"));
link_info.disable_target_specific_optimizations = -1;
DISABLE_RELAXATION;
}
return TRUE;

View File

@ -1,6 +1,5 @@
/* ldmain.h -
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2002, 2003, 2004,
2005, 2007, 2008, 2009, 2012 Free Software Foundation, Inc.
Copyright 1991-2013 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
@ -42,11 +41,16 @@ extern int overflow_cutoff_limit;
#define RELAXATION_DISABLED_BY_DEFAULT \
(link_info.disable_target_specific_optimizations < 0)
#define RELAXATION_DISABLED_BY_USER \
(link_info.disable_target_specific_optimizations > 0)
(link_info.disable_target_specific_optimizations > 1)
#define RELAXATION_ENABLED \
(link_info.disable_target_specific_optimizations == 0 \
|| link_info.disable_target_specific_optimizations == 1)
#define RELAXATION_ENABLED_BY_USER \
(link_info.disable_target_specific_optimizations == 0)
#define DISABLE_RELAXATION \
#define TARGET_ENABLE_RELAXATION \
do { link_info.disable_target_specific_optimizations = 1; } while (0)
#define DISABLE_RELAXATION \
do { link_info.disable_target_specific_optimizations = 2; } while (0)
#define ENABLE_RELAXATION \
do { link_info.disable_target_specific_optimizations = 0; } while (0)

View File

@ -35,6 +35,31 @@ MEMORY
SECTIONS
{
/* Bootloader. */
.bootloader ${RELOCATING-0} :
{
${RELOCATING+ PROVIDE (__boot_start = .) ; }
*(.bootloader)
${RELOCATING+. = ALIGN(2);}
*(.bootloader.*)
} ${RELOCATING+ > bootloader}
/* Information memory. */
.infomem ${RELOCATING-0} :
{
*(.infomem)
${RELOCATING+. = ALIGN(2);}
*(.infomem.*)
} ${RELOCATING+ > infomem}
/* Information memory (not loaded into MPU). */
.infomemnobits ${RELOCATING-0} :
{
*(.infomemnobits)
${RELOCATING+. = ALIGN(2);}
*(.infomemnobits.*)
} ${RELOCATING+ > infomemnobits}
/* Read-only sections, merged into text segment. */
${TEXT_DYNAMIC+${DYNAMIC}}
.hash ${RELOCATING-0} : { *(.hash) }
@ -122,6 +147,8 @@ SECTIONS
*(.text)
${RELOCATING+. = ALIGN(2);}
*(.text.*)
${RELOCATING+. = ALIGN(2);}
*(.text:*)
${RELOCATING+. = ALIGN(2);}
*(SORT_NONE(.fini9))
@ -139,42 +166,84 @@ SECTIONS
_etext = .;
} ${RELOCATING+ > text}
.data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
.rodata :
{
. = ALIGN(2);
*(.plt)
*(.rodata .rodata.* .gnu.linkonce.r.* .const .const:*)
*(.rodata1)
*(.eh_frame_hdr)
KEEP (*(.eh_frame))
KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
LONG(0); /* Sentinel. */
/* gcc uses crtbegin.o to find the start of the constructors, so
we make sure it is first. Because this is a wildcard, it
doesn't matter if the user does not actually link against
crtbegin.o; the linker won't look for a file to match a
wildcard. The wildcard also means that it doesn't matter which
directory crtbegin.o is in. */
KEEP (*crtbegin*.o(.ctors))
/* We don't want to include the .ctor section from from the
crtend.o file until after the sorted ctors. The .ctor section
from the crtend file contains the end of ctors marker and it
must be last */
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*crtbegin*.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} ${RELOCATING+ > text}
.vectors ${RELOCATING-0}:
{
${RELOCATING+ PROVIDE (__vectors_start = .) ; }
*(.vectors*)
${RELOCATING+ _vectors_end = . ; }
} ${RELOCATING+ > vectors}
.data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata))}
{
${RELOCATING+ PROVIDE (__data_start = .) ; }
${RELOCATING+ PROVIDE (__datastart = .) ; }
${RELOCATING+. = ALIGN(2);}
KEEP (*(.jcr))
*(.data.rel.ro.local) *(.data.rel.ro*)
*(.dynamic)
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
KEEP (*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.got.plt) *(.got)
${RELOCATING+. = ALIGN(2);}
*(.sdata .sdata.* .gnu.linkonce.s.*)
${RELOCATING+. = ALIGN(2);}
${RELOCATING+ _edata = . ; }
} ${RELOCATING+ > data}
/* Bootloader. */
.bootloader ${RELOCATING-0} :
{
${RELOCATING+ PROVIDE (__boot_start = .) ; }
*(.bootloader)
${RELOCATING+. = ALIGN(2);}
*(.bootloader.*)
} ${RELOCATING+ > bootloader}
/* Information memory. */
.infomem ${RELOCATING-0} :
{
*(.infomem)
${RELOCATING+. = ALIGN(2);}
*(.infomem.*)
} ${RELOCATING+ > infomem}
/* Information memory (not loaded into MPU). */
.infomemnobits ${RELOCATING-0} :
{
*(.infomemnobits)
${RELOCATING+. = ALIGN(2);}
*(.infomemnobits.*)
} ${RELOCATING+ > infomemnobits}
.bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
{
${RELOCATING+. = ALIGN(2);}
@ -194,13 +263,6 @@ SECTIONS
${RELOCATING+ _end = . ; }
} ${RELOCATING+ > data}
.vectors ${RELOCATING-0}:
{
${RELOCATING+ PROVIDE (__vectors_start = .) ; }
*(.vectors*)
${RELOCATING+ _vectors_end = . ; }
} ${RELOCATING+ > vectors}
${HEAP_SECTION_MSP430}
/* Stabs for profiling information*/
@ -214,12 +276,18 @@ SECTIONS
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
EOF
. $srcdir/scripttempl/DWARF.sc
source $srcdir/scripttempl/DWARF.sc
cat <<EOF
.MP430.attributes 0 :
{
KEEP (*(.MSP430.attributes))
KEEP (*(.gnu.attributes))
KEEP (*(__TI_build_attributes))
}
PROVIDE (__stack = ${STACK}) ;
PROVIDE (__data_start_rom = _etext) ;
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ;

View File

@ -98,6 +98,8 @@ SECTIONS
*(.text)
${RELOCATING+. = ALIGN(2);}
*(.text.*)
${RELOCATING+. = ALIGN(2);}
*(.text:*)
${RELOCATING+. = ALIGN(2);}
*(SORT_NONE(.fini9))
@ -115,6 +117,13 @@ SECTIONS
${RELOCATING+ _etext = . ; }
} ${RELOCATING+ > text}
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.const)
*(.const:*)
} ${RELOCATING+ > text}
.data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
{
${RELOCATING+ PROVIDE (__data_start = .) ; }
@ -152,6 +161,13 @@ SECTIONS
${RELOCATING+ _vectors_end = . ; }
} ${RELOCATING+ > vectors}
.MP430.attributes 0 :
{
KEEP (*(.MSP430.attributes))
KEEP (*(.gnu.attributes))
KEEP (*(__TI_build_attributes))
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }

View File

@ -1,3 +1,15 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* ld-elf/flags1.d: Expect this test to pass on the MSP430.
* ld-elf/init-fini-arrays.d: Expect this test to fail on the
MSP430.
* ld-elf/merge.d: Expect this test to pass on the MSP430.
* ld-elf/sec64k.exp: Skip these tests for the MSP430.
* ld-gc/pr13683.d: Expect this test to fail on the MSP430.
* ld-srec/srec.exp: Expect these tests to fail on the MSP430.
* ld-undefined/undefined.exp: Expect the UNDEFINED LINE test to
fail on the MSP430.
2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
* lib/ld-lib.exp (check_shared_lib_support): Also exclude

View File

@ -3,9 +3,9 @@
#objcopy_linked_file: --set-section-flags .post_text_reserve=contents,alloc,load,readonly,code
#readelf: -l --wide
#xfail: "avr-*-*" "dlx-*-*" "h8300-*-*" "i960-*-*" "ip2k-*-*" "m32r-*-*"
#xfail: "moxie-*-*" "mt-*-*" "msp430-*-*" "*-*-nacl*"
#xfail: "moxie-*-*" "mt-*-*" "*-*-nacl*"
#xfail: "*-*-hpux*" "hppa*64*-*-*"
# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT, and MSP430,
# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT,
# and all NaCl targets,
# because the two sections are not merged into one segment.
# (There is no good reason why they have to be).

View File

@ -1,9 +1,10 @@
#source: init-fini-arrays.s
#ld: -r
#readelf: -S --wide
#xfail: cr16-*-* crx-*-*
#xfail: cr16-*-* crx-*-* msp430-*-*
# msp430 puts the init_array and fini_array inside the .rodata section.
# cr16 and crx use non-standard scripts with memory regions, which don't play
# well with unique group sections under ld -r.
# well with unique group sections under ld -r.
#...
\[[ 0-9]+\] \.init_array\.01000[ \t]+PROGBITS[ \t0-9a-f]+WA?.*

View File

@ -4,7 +4,7 @@
#xfail: "arc-*-*" "avr-*-*" "bfin-*-*" "cr16-*-*" "cris*-*-*" "crx-*-*" "d10v-*-*" "d30v-*-*"
#xfail: "dlx-*-*" "fr30-*-*" "frv-*-*" "hppa*64*-*-*" "h8300-*-*" "score-*-*"
#xfail: "i370-*-*" "i860-*-*" "i960-*-*" "ip2k-*-*" "iq2000-*-*" "lm32-*-*"
#xfail: "mcore-*-*" "mn102*-*-*" "mips*-*-*" "ms1-*-*" "msp430-*-*" "mep-*-*"
#xfail: "mcore-*-*" "mn102*-*-*" "mips*-*-*" "ms1-*-*" "mep-*-*"
#xfail: "or32-*-*" "pj-*-*" "sparc*-*-*" "tic6x-*-*" "vax-*-*" "xstormy16-*-*"
#xfail: "xtensa*-*-*" "metag-*-*"

View File

@ -34,6 +34,7 @@ if { [istarget "arc-*-*"]
|| [istarget "d30v-*-*"]
|| [istarget "dlx-*-*"]
|| [istarget "i960-*-*"]
|| [istarget "msp430*-*-*"]
|| [istarget "or32-*-*"]
|| [istarget "pj*-*-*"]
|| [istarget "m32r-*-*"] } {

View File

@ -2,7 +2,7 @@
#source: dummy.s
#ld: --gc-sections -e main --defsym foo=foo2 tmpdir/pr13683.o
#nm: --format=bsd
#xfail: sh64*-*-* iq2000-*-* lm32-*-* epiphany-*-* mips64vr-*-* frv-*-* m32c-*-* rl78-*-* rx-*-* sh-*-* powerpc*-*-eabivle
#xfail: sh64*-*-* iq2000-*-* lm32-*-* epiphany-*-* mips64vr-*-* frv-*-* m32c-*-* rl78-*-* rx-*-* sh-*-* powerpc*-*-eabivle msp430-*-*
# Note - look for both "foo" and "foo2" being defined, non-zero function symbols

View File

@ -1,7 +1,6 @@
# Test linking directly to S-records.
# By Ian Lance Taylor, Cygnus Support.
# Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2011, 2012
# Free Software Foundation, Inc.
# Copyright 1999-2013 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
@ -269,6 +268,11 @@ proc run_srec_test { test objs } {
set flags "$flags -no-relax"
}
# MSP430 targets always relax.
if [istarget msp430*-*-*] {
setup_xfail "msp430*-*-*"
}
# Epiphany needs some help too
if [istarget epiphany*-*-*] {
set flags "$flags --defsym _start=00000060"

View File

@ -128,6 +128,11 @@ setup_xfail mcore-*-elf
setup_xfail mep-*-*
setup_xfail mips-sgi-irix6*
setup_xfail "sh64-*-*"
# Fails for the MSP430 because it uses SYM_DIFF relocs but it does
# not provide a special_function for handling them. If optimization
# is enabled then this test passes because function()'s prologue is
# eliminated.
setup_xfail "msp430-*-*"
# The undefined test fails on 31 bit s/390 because the address of the
# function `this_function_is_not_defined' is stored in the literal pool of

View File

@ -1,3 +1,7 @@
2013-05-02 Nick Clifton <nickc@redhat.com>
* msp430-dis.c: Add support for MSP430X instructions.
2013-04-24 Sandra Loosemore <sandra@codesourcery.com>
* nios2-opc.c (nios2_builtin_reg): Rename "fstatus" control register

View File

@ -1,7 +1,6 @@
/* Disassemble MSP430 instructions.
Copyright (C) 2002, 2004, 2005, 2007, 2009, 2010, 2012
Free Software Foundation, Inc.
Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of the GNU opcodes library.
@ -82,6 +81,52 @@ msp430_nooperands (struct msp430_opcode_s *opcode,
return 2;
}
static int
print_as2_reg_name (int regno, char * op1, char * comm1,
int c2, int c3, int cd)
{
switch (regno)
{
case 2:
sprintf (op1, "#4");
sprintf (comm1, "r2 As==10");
return c2;
case 3:
sprintf (op1, "#2");
sprintf (comm1, "r3 As==10");
return c3;
default:
/* Indexed register mode @Rn. */
sprintf (op1, "@r%d", regno);
return cd;
}
}
static int
print_as3_reg_name (int regno, char * op1, char * comm1,
int c2, int c3, int cd)
{
switch (regno)
{
case 2:
sprintf (op1, "#8");
sprintf (comm1, "r2 As==11");
return c2;
case 3:
sprintf (op1, "#-1");
sprintf (comm1, "r3 As==11");
return c3;
default:
/* Post incremented @Rn+. */
sprintf (op1, "@r%d+", regno);
return cd;
}
}
static int
msp430_singleoperand (disassemble_info *info,
struct msp430_opcode_s *opcode,
@ -89,20 +134,28 @@ msp430_singleoperand (disassemble_info *info,
unsigned short insn,
char *op,
char *comm,
unsigned short extension_word,
int *cycles)
{
int regs = 0, regd = 0;
int ad = 0, as = 0;
int where = 0;
int cmd_len = 2;
short dst = 0;
int dst = 0;
int fmt;
int extended_dst = extension_word & 0xf;
regd = insn & 0x0f;
regs = (insn & 0x0f00) >> 8;
as = (insn & 0x0030) >> 4;
ad = (insn & 0x0080) >> 7;
switch (opcode->fmt)
if (opcode->fmt < 0)
fmt = (- opcode->fmt) - 1;
else
fmt = opcode->fmt;
switch (fmt)
{
case 0: /* Emulated work with dst register. */
if (regs != 2 && regs != 3 && regs != 1)
@ -146,6 +199,13 @@ msp430_singleoperand (disassemble_info *info,
sprintf (op, "0x%04x", dst);
sprintf (comm, "PC rel. abs addr 0x%04x",
PS ((short) (addr + 2) + dst));
if (extended_dst)
{
dst |= extended_dst << 16;
sprintf (op, "0x%05x", dst);
sprintf (comm, "PC rel. abs addr 0x%05lx",
(long)((addr + 2 + dst) & 0xfffff));
}
}
else if (regd == 2)
{
@ -154,12 +214,25 @@ msp430_singleoperand (disassemble_info *info,
cmd_len += 2;
*cycles = 4;
sprintf (op, "&0x%04x", PS (dst));
if (extended_dst)
{
dst |= extended_dst << 16;
sprintf (op, "&0x%05x", dst & 0xfffff);
}
}
else
{
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
*cycles = 4;
if (extended_dst)
{
dst |= extended_dst << 16;
if (dst & 0x80000)
dst |= -1 << 20;
}
else if (dst & 0x8000)
dst |= -1 << 16;
sprintf (op, "%d(r%d)", dst, regd);
}
}
@ -183,51 +256,31 @@ msp430_singleoperand (disassemble_info *info,
}
else if (as == 2)
{
*cycles = 1;
if (regd == 2)
{
sprintf (op, "#4");
sprintf (comm, "r2 As==10");
}
else if (regd == 3)
{
sprintf (op, "#2");
sprintf (comm, "r3 As==10");
}
else
{
*cycles = 3;
/* Indexed register mode @Rn. */
sprintf (op, "@r%d", regd);
}
* cycles = print_as2_reg_name (regd, op, comm, 1, 1, 3);
}
else if (as == 3)
{
*cycles = 1;
if (regd == 2)
{
sprintf (op, "#8");
sprintf (comm, "r2 As==11");
}
else if (regd == 3)
{
sprintf (op, "#-1");
sprintf (comm, "r3 As==11");
}
else if (regd == 0)
if (regd == 0)
{
*cycles = 3;
/* absolute. @pc+ */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
sprintf (op, "#%d", dst);
sprintf (comm, "#0x%04x", PS (dst));
if (dst > 9 || dst < 0)
sprintf (comm, "#0x%04x", PS (dst));
if (extended_dst)
{
dst |= extended_dst << 16;
if (dst & 0x80000)
dst |= -1 << 20;
sprintf (op, "#%d", dst);
if (dst > 9 || dst < 0)
sprintf (comm, "#0x%05x", dst);
}
}
else
{
*cycles = 3;
sprintf (op, "@r%d+", regd);
}
* cycles = print_as3_reg_name (regd, op, comm, 1, 1, 3);
}
else if (as == 1)
{
@ -240,6 +293,13 @@ msp430_singleoperand (disassemble_info *info,
sprintf (op, "0x%04x", PS (dst));
sprintf (comm, "PC rel. 0x%04x",
PS ((short) addr + 2 + dst));
if (extended_dst)
{
dst |= extended_dst << 16;
sprintf (op, "0x%05x", dst & 0xffff);
sprintf (comm, "PC rel. 0x%05lx",
(long)((addr + 2 + dst) & 0xfffff));
}
}
else if (regd == 2)
{
@ -247,6 +307,11 @@ msp430_singleoperand (disassemble_info *info,
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
sprintf (op, "&0x%04x", PS (dst));
if (extended_dst)
{
dst |= extended_dst << 16;
sprintf (op, "&0x%05x", dst & 0xfffff);
}
}
else if (regd == 3)
{
@ -256,10 +321,20 @@ msp430_singleoperand (disassemble_info *info,
}
else
{
/* Indexd. */
/* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
if (extended_dst)
{
dst |= extended_dst << 16;
if (dst & 0x80000)
dst |= -1 << 20;
}
else if (dst & 0x8000)
dst |= -1 << 16;
sprintf (op, "%d(r%d)", dst, regd);
if (dst > 9 || dst < 0)
sprintf (comm, "%05x", dst);
}
}
break;
@ -273,7 +348,7 @@ msp430_singleoperand (disassemble_info *info,
where *= 2;
sprintf (op, "$%+-8d", where + 2);
sprintf (comm, "abs 0x%x", PS ((short) (addr) + 2 + where));
sprintf (comm, "abs 0x%lx", (long) (addr + 2 + where));
*cycles = 2;
return 2;
break;
@ -293,19 +368,28 @@ msp430_doubleoperand (disassemble_info *info,
char *op2,
char *comm1,
char *comm2,
unsigned short extension_word,
int *cycles)
{
int regs = 0, regd = 0;
int ad = 0, as = 0;
int cmd_len = 2;
short dst = 0;
int dst = 0;
int fmt;
int extended_dst = extension_word & 0xf;
int extended_src = (extension_word >> 7) & 0xf;
regd = insn & 0x0f;
regs = (insn & 0x0f00) >> 8;
as = (insn & 0x0030) >> 4;
ad = (insn & 0x0080) >> 7;
if (opcode->fmt == 0)
if (opcode->fmt < 0)
fmt = (- opcode->fmt) - 1;
else
fmt = opcode->fmt;
if (fmt == 0)
{
/* Special case: rla and rlc are the only 2 emulated instructions that
fall into two operand instructions. */
@ -343,7 +427,15 @@ msp430_doubleoperand (disassemble_info *info,
sprintf (op1, "0x%04x", PS (dst));
sprintf (comm1, "PC rel. 0x%04x",
PS ((short) addr + 2 + dst));
if (extended_dst)
{
dst |= extended_dst << 16;
if (dst & 0x80000)
dst |= -1 << 20;
sprintf (op1, "0x%05x", dst & 0xfffff);
sprintf (comm1, "PC rel. 0x%05lx",
(long)((addr + 2 + dst) & 0xfffff));
}
}
else if (regd == 2)
{
@ -356,19 +448,35 @@ msp430_doubleoperand (disassemble_info *info,
cmd_len += 4;
*cycles = 6;
sprintf (op1, "&0x%04x", PS (dst));
if (extended_dst)
{
dst |= extended_dst << 16;
sprintf (op1, "&0x%05x", dst & 0xfffff);
}
}
else
{
/* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
if (extended_dst)
{
dst |= extended_dst << 16;
if (dst & 0x80000)
dst |= -1 << 20;
}
else if (dst & 0x8000)
dst |= -1 << 16;
cmd_len += 4;
*cycles = 6;
sprintf (op1, "%d(r%d)", dst, regd);
if (dst > 9 || dst < -9)
sprintf (comm1, "#0x%05x", dst);
}
}
*op2 = 0;
*comm2 = 0;
return cmd_len;
}
@ -386,7 +494,7 @@ msp430_doubleoperand (disassemble_info *info,
*cycles = 1;
if (regs == 3)
{
/* Constsnts. */
/* Constants. */
sprintf (op1, "#0");
sprintf (comm1, "r3 As==00");
}
@ -398,56 +506,31 @@ msp430_doubleoperand (disassemble_info *info,
}
else if (as == 2)
{
*cycles = 1;
if (regs == 2)
{
sprintf (op1, "#4");
sprintf (comm1, "r2 As==10");
}
else if (regs == 3)
{
sprintf (op1, "#2");
sprintf (comm1, "r3 As==10");
}
else
{
*cycles = 2;
/* Indexed register mode @Rn. */
sprintf (op1, "@r%d", regs);
}
if (!regs)
*cycles = 3;
* cycles = print_as2_reg_name (regs, op1, comm1, 1, 1, regs == 0 ? 3 : 2);
}
else if (as == 3)
{
if (regs == 2)
{
sprintf (op1, "#8");
sprintf (comm1, "r2 As==11");
*cycles = 1;
}
else if (regs == 3)
{
sprintf (op1, "#-1");
sprintf (comm1, "r3 As==11");
*cycles = 1;
}
else if (regs == 0)
if (regs == 0)
{
*cycles = 3;
/* Absolute. @pc+. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
sprintf (op1, "#%d", dst);
sprintf (comm1, "#0x%04x", PS (dst));
if (dst > 9 || dst < 0)
sprintf (comm1, "#0x%04x", PS (dst));
if (extended_src)
{
dst |= extended_src << 16;
if (dst & 0x80000)
dst |= -1 << 20;
sprintf (op1, "#%d", dst);
if (dst > 9 || dst < 0)
sprintf (comm1, "0x%05x", dst & 0xfffff);
}
}
else
{
*cycles = 2;
sprintf (op1, "@r%d+", regs);
}
* cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
}
else if (as == 1)
{
@ -460,6 +543,15 @@ msp430_doubleoperand (disassemble_info *info,
sprintf (op1, "0x%04x", PS (dst));
sprintf (comm1, "PC rel. 0x%04x",
PS ((short) addr + 2 + dst));
if (extended_src)
{
dst |= extended_src << 16;
if (dst & 0x80000)
dst |= -1 << 20;
sprintf (op1, "0x%05x", dst & 0xfffff);
sprintf (comm1, "PC rel. 0x%05lx",
(long) ((addr + 2 + dst) & 0xfffff));
}
}
else if (regs == 2)
{
@ -469,6 +561,12 @@ msp430_doubleoperand (disassemble_info *info,
cmd_len += 2;
sprintf (op1, "&0x%04x", PS (dst));
sprintf (comm1, "0x%04x", PS (dst));
if (extended_src)
{
dst |= extended_src << 16;
sprintf (op1, "&0x%05x", dst & 0xfffff);
* comm1 = 0;
}
}
else if (regs == 3)
{
@ -482,7 +580,17 @@ msp430_doubleoperand (disassemble_info *info,
/* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
if (extended_src)
{
dst |= extended_src << 16;
if (dst & 0x80000)
dst |= -1 << 20;
}
else if (dst & 0x8000)
dst |= -1 << 16;
sprintf (op1, "%d(r%d)", dst, regs);
if (dst > 9 || dst < -9)
sprintf (comm1, "0x%05x", dst);
}
}
@ -517,6 +625,15 @@ msp430_doubleoperand (disassemble_info *info,
sprintf (op2, "0x%04x", PS (dst));
sprintf (comm2, "PC rel. 0x%04x",
PS ((short) addr + cmd_len + dst));
if (extended_dst)
{
dst |= extended_dst << 16;
if (dst & 0x80000)
dst |= -1 << 20;
sprintf (op2, "0x%05x", dst & 0xfffff);
sprintf (comm2, "PC rel. 0x%05lx",
(long)((addr + cmd_len + dst) & 0xfffff));
}
cmd_len += 2;
}
else if (regd == 2)
@ -525,11 +642,28 @@ msp430_doubleoperand (disassemble_info *info,
dst = msp430dis_opcode (addr + cmd_len, info);
cmd_len += 2;
sprintf (op2, "&0x%04x", PS (dst));
if (extended_dst)
{
dst |= extended_dst << 16;
sprintf (op2, "&0x%05x", dst & 0xfffff);
}
}
else
{
dst = msp430dis_opcode (addr + cmd_len, info);
cmd_len += 2;
if (dst & 0x8000)
dst |= -1 << 16;
if (dst > 9 || dst < 0)
sprintf (comm2, "0x%04x", PS (dst));
if (extended_dst)
{
dst |= extended_dst << 16;
if (dst & 0x80000)
dst |= -1 << 20;
if (dst > 9 || dst < 0)
sprintf (comm2, "0x%05x", dst & 0xfffff);
}
sprintf (op2, "%d(r%d)", dst, regd);
}
}
@ -577,40 +711,11 @@ msp430_branchinstr (disassemble_info *info,
}
else if (as == 2)
{
if (regs == 2)
{
*cycles = 2;
sprintf (op1, "#4");
sprintf (comm1, "r2 As==10");
}
else if (regs == 3)
{
*cycles = 1;
sprintf (op1, "#2");
sprintf (comm1, "r3 As==10");
}
else
{
/* Indexed register mode @Rn. */
*cycles = 2;
sprintf (op1, "@r%d", regs);
}
* cycles = print_as2_reg_name (regs, op1, comm1, 2, 1, 2);
}
else if (as == 3)
{
if (regs == 2)
{
*cycles = 1;
sprintf (op1, "#8");
sprintf (comm1, "r2 As==11");
}
else if (regs == 3)
{
*cycles = 1;
sprintf (op1, "#-1");
sprintf (comm1, "r3 As==11");
}
else if (regs == 0)
if (regs == 0)
{
/* Absolute. @pc+ */
*cycles = 3;
@ -619,10 +724,7 @@ msp430_branchinstr (disassemble_info *info,
sprintf (op1, "#0x%04x", PS (dst));
}
else
{
*cycles = 2;
sprintf (op1, "@r%d+", regs);
}
* cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
}
else if (as == 1)
{
@ -653,9 +755,11 @@ msp430_branchinstr (disassemble_info *info,
}
else
{
/* Indexd. */
/* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
if (dst & 0x8000)
dst |= -1 << 16;
sprintf (op1, "%d(r%d)", dst, regs);
}
}
@ -663,6 +767,82 @@ msp430_branchinstr (disassemble_info *info,
return cmd_len;
}
static int
msp430x_calla_instr (disassemble_info * info,
bfd_vma addr,
unsigned short insn,
char * op1,
char * comm1,
int * cycles)
{
unsigned int ureg = insn & 0xf;
int reg = insn & 0xf;
int am = (insn & 0xf0) >> 4;
int cmd_len = 2;
unsigned short udst = 0;
short dst = 0;
switch (am)
{
case 4: /* CALLA Rdst */
*cycles = 1;
sprintf (op1, "r%d", reg);
break;
case 5: /* CALLA x(Rdst) */
*cycles = 3;
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
sprintf (op1, "%d(r%d)", dst, reg);
if (reg == 0)
sprintf (comm1, "PC rel. 0x%05lx", (long) (addr + 2 + dst));
else
sprintf (comm1, "0x%05x", dst);
break;
case 6: /* CALLA @Rdst */
*cycles = 2;
sprintf (op1, "@r%d", reg);
break;
case 7: /* CALLA @Rdst+ */
*cycles = 2;
sprintf (op1, "@r%d+", reg);
break;
case 8: /* CALLA &abs20 */
udst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
*cycles = 4;
sprintf (op1, "&%d", (ureg << 16) + udst);
sprintf (comm1, "0x%05x", (ureg << 16) + udst);
break;
case 9: /* CALLA pcrel-sym */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
*cycles = 4;
sprintf (op1, "%d(PC)", (reg << 16) + dst);
sprintf (comm1, "PC rel. 0x%05lx",
(long) (addr + 2 + dst + (reg << 16)));
break;
case 11: /* CALLA #imm20 */
udst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
*cycles = 4;
sprintf (op1, "#%d", (ureg << 16) + udst);
sprintf (comm1, "0x%05x", (ureg << 16) + udst);
break;
default:
strcpy (comm1, _("unercognised CALLA addressing mode"));
return -1;
}
return cmd_len;
}
int
print_insn_msp430 (bfd_vma addr, disassemble_info *info)
{
@ -674,10 +854,14 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
unsigned short insn;
int cycles = 0;
char *bc = "";
char dinfo[32]; /* Debug purposes. */
unsigned short extension_word = 0;
insn = msp430dis_opcode (addr, info);
sprintf (dinfo, "0x%04x", insn);
if (insn == (unsigned short) -1)
{
prin (stream, ".word 0xffff; ????");
return 2;
}
if (((int) addr & 0xffff) > 0xffdf)
{
@ -688,6 +872,20 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
*comm1 = 0;
*comm2 = 0;
/* Check for an extension word. */
if ((insn & 0xf800) == 0x1800)
{
extension_word = insn;
addr += 2;
insn = msp430dis_opcode (addr, info);
if (insn == (unsigned short) -1)
{
prin (stream, ".word 0x%04x, 0xffff; ????",
extension_word);
return 4;
}
}
for (opcode = msp430_opcodes; opcode->name; opcode++)
{
if ((insn & opcode->bin_mask) == opcode->bin_opcode
@ -699,34 +897,257 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
*comm2 = 0;
/* r0 as destination. Ad should be zero. */
if (opcode->insn_opnumb == 3 && (insn & 0x000f) == 0
&& (0x0080 & insn) == 0)
if (opcode->insn_opnumb == 3
&& (insn & 0x000f) == 0
&& (insn & 0x0080) == 0)
{
cmd_len =
cmd_len +=
msp430_branchinstr (info, opcode, addr, insn, op1, comm1,
&cycles);
if (cmd_len)
break;
}
switch (opcode->insn_opnumb)
{
int n;
int reg;
case 4:
cmd_len += msp430x_calla_instr (info, addr, insn,
op1, comm1, & cycles);
break;
case 5: /* PUSHM/POPM */
n = (insn & 0xf0) >> 4;
reg = (insn & 0xf);
sprintf (op1, "#%d", n + 1);
if (opcode->bin_opcode == 0x1400)
/* PUSHM */
sprintf (op2, "r%d", reg);
else
/* POPM */
sprintf (op2, "r%d", reg + n);
if (insn & 0x100)
sprintf (comm1, "16-bit words");
else
{
sprintf (comm1, "20-bit words");
bc =".a";
}
cycles = 2; /*FIXME*/
cmd_len = 2;
break;
case 6: /* RRAM, RRCM, RRUM, RLAM. */
n = ((insn >> 10) & 0x3) + 1;
reg = (insn & 0xf);
if ((insn & 0x10) == 0)
bc =".a";
sprintf (op1, "#%d", n);
sprintf (op2, "r%d", reg);
cycles = 2; /*FIXME*/
cmd_len = 2;
break;
case 8: /* ADDA, CMPA, SUBA. */
reg = (insn & 0xf);
n = (insn >> 8) & 0xf;
if (insn & 0x40)
{
sprintf (op1, "r%d", n);
cmd_len = 2;
}
else
{
n <<= 16;
n |= msp430dis_opcode (addr + 2, info);
sprintf (op1, "#%d", n);
if (n > 9 || n < 0)
sprintf (comm1, "0x%05x", n);
cmd_len = 4;
}
sprintf (op2, "r%d", reg);
cycles = 2; /*FIXME*/
break;
case 9: /* MOVA */
reg = (insn & 0xf);
n = (insn >> 8) & 0xf;
switch ((insn >> 4) & 0xf)
{
case 0: /* MOVA @Rsrc, Rdst */
cmd_len = 2;
sprintf (op1, "@r%d", n);
if (strcmp (opcode->name, "bra") != 0)
sprintf (op2, "r%d", reg);
break;
case 1: /* MOVA @Rsrc+, Rdst */
cmd_len = 2;
if (strcmp (opcode->name, "reta") != 0)
{
sprintf (op1, "@r%d+", n);
if (strcmp (opcode->name, "bra") != 0)
sprintf (op2, "r%d", reg);
}
break;
case 2: /* MOVA &abs20, Rdst */
cmd_len = 4;
n <<= 16;
n |= msp430dis_opcode (addr + 2, info);
sprintf (op1, "&%d", n);
if (n > 9 || n < 0)
sprintf (comm1, "0x%05x", n);
if (strcmp (opcode->name, "bra") != 0)
sprintf (op2, "r%d", reg);
break;
case 3: /* MOVA x(Rsrc), Rdst */
cmd_len = 4;
if (strcmp (opcode->name, "bra") != 0)
sprintf (op2, "r%d", reg);
reg = n;
n = msp430dis_opcode (addr + 2, info);
if (n & 0x8000)
n |= -1 << 16;
sprintf (op1, "%d(r%d)", n, reg);
if (n > 9 || n < 0)
{
if (reg == 0)
sprintf (comm1, "PC rel. 0x%05lx",
(long) (addr + 2 + n));
else
sprintf (comm1, "0x%05x", n);
}
break;
case 6: /* MOVA Rsrc, &abs20 */
cmd_len = 4;
reg <<= 16;
reg |= msp430dis_opcode (addr + 2, info);
sprintf (op1, "r%d", n);
sprintf (op2, "&%d", reg);
if (reg > 9 || reg < 0)
sprintf (comm2, "0x%05x", reg);
break;
case 7: /* MOVA Rsrc, x(Rdst) */
cmd_len = 4;
sprintf (op1, "r%d", n);
n = msp430dis_opcode (addr + 2, info);
if (n & 0x8000)
n |= -1 << 16;
sprintf (op2, "%d(r%d)", n, reg);
if (n > 9 || n < 0)
{
if (reg == 0)
sprintf (comm2, "PC rel. 0x%05lx",
(long) (addr + 2 + n));
else
sprintf (comm2, "0x%05x", n);
}
break;
case 8: /* MOVA #imm20, Rdst */
cmd_len = 4;
n <<= 16;
n |= msp430dis_opcode (addr + 2, info);
if (n & 0x80000)
n |= -1 << 20;
sprintf (op1, "#%d", n);
if (n > 9 || n < 0)
sprintf (comm1, "0x%05x", n);
if (strcmp (opcode->name, "bra") != 0)
sprintf (op2, "r%d", reg);
break;
case 12: /* MOVA Rsrc, Rdst */
cmd_len = 2;
sprintf (op1, "r%d", n);
if (strcmp (opcode->name, "bra") != 0)
sprintf (op2, "r%d", reg);
break;
default:
break;
}
cycles = 2; /* FIXME */
break;
}
if (cmd_len)
break;
switch (opcode->insn_opnumb)
{
case 0:
cmd_len = msp430_nooperands (opcode, addr, insn, comm1, &cycles);
cmd_len += msp430_nooperands (opcode, addr, insn, comm1, &cycles);
break;
case 2:
cmd_len =
cmd_len +=
msp430_doubleoperand (info, opcode, addr, insn, op1, op2,
comm1, comm2, &cycles);
comm1, comm2,
extension_word,
&cycles);
if (insn & BYTE_OPERATION)
bc = ".b";
{
if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
bc = ".a";
else
bc = ".b";
}
else if (extension_word)
{
if (extension_word & (1 << 6))
bc = ".w";
else
{
bc = ".?";
sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
}
}
break;
case 1:
cmd_len =
cmd_len +=
msp430_singleoperand (info, opcode, addr, insn, op1, comm1,
extension_word,
&cycles);
if (insn & BYTE_OPERATION && opcode->fmt != 3)
bc = ".b";
if (extension_word
&& (strcmp (opcode->name, "swpb") == 0
|| strcmp (opcode->name, "sxt") == 0))
{
if (insn & BYTE_OPERATION)
{
bc = ".?";
sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
}
else if (extension_word & BYTE_OPERATION)
bc = ".w";
else
bc = ".a";
}
else if (insn & BYTE_OPERATION && opcode->fmt != 3)
{
if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
bc = ".a";
else
bc = ".b";
}
else if (extension_word)
{
if (extension_word & (1 << 6))
bc = ".w";
else
{
bc = ".?";
sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
}
}
break;
default:
break;
@ -737,16 +1158,33 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
break;
}
dinfo[5] = 0;
if (cmd_len < 1)
{
/* Unknown opcode, or invalid combination of operands. */
if (extension_word)
{
prin (stream, ".word 0x%04x, 0x%04x; ????", extension_word, PS (insn));
if (*comm1)
prin (stream, "\t %s", comm1);
return 4;
}
(*prin) (stream, ".word 0x%04x; ????", PS (insn));
return 2;
}
(*prin) (stream, "%s%s", opcode->name, bc);
/* Display the repeat count (if set) for extended register mode. */
if (cmd_len == 2 && ((extension_word & 0xf) != 0))
{
if (extension_word & (1 << 7))
prin (stream, "rpt r%d { ", extension_word & 0xf);
else
prin (stream, "rpt #%d { ", (extension_word & 0xf) + 1);
}
if (extension_word && opcode->name[strlen (opcode->name) - 1] != 'x')
(*prin) (stream, "%sx%s", opcode->name, bc);
else
(*prin) (stream, "%s%s", opcode->name, bc);
if (*op1)
(*prin) (stream, "\t%s", op1);
@ -783,5 +1221,9 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
(*prin) (stream, ",");
if (*comm2)
(*prin) (stream, " %s", comm2);
if (extension_word)
cmd_len += 2;
return cmd_len;
}