summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2003-03-25 20:56:01 +0000
committerNick Clifton <nickc@redhat.com>2003-03-25 20:56:01 +0000
commit3c228517adac7fbf03219f067fa0e9380e7c05ce (patch)
tree3f21827b2ccae80ff766209c94ae290257525201
parentbfc3a2046eeab959642f75e0a8d2bfade9305a2d (diff)
downloadgdb-3c228517adac7fbf03219f067fa0e9380e7c05ce.tar.gz
Add iWMMXt support
-rw-r--r--bfd/ChangeLog23
-rw-r--r--bfd/archures.c1
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/coff-arm.c57
-rw-r--r--bfd/coffcode.h21
-rw-r--r--bfd/coffgen.c3
-rw-r--r--bfd/cpu-arm.c6
-rw-r--r--bfd/elf32-arm.h119
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c2
-rw-r--r--include/coff/ChangeLog7
-rw-r--r--include/coff/arm.h2
-rw-r--r--include/elf/ChangeLog9
-rw-r--r--include/elf/arm.h3
-rw-r--r--opcodes/ChangeLog11
-rw-r--r--opcodes/arm-dis.c185
-rw-r--r--opcodes/arm-opc.h62
17 files changed, 487 insertions, 27 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e0f41fda6eb..a29b48ace47 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,26 @@
+2003-03-25 Stan Cox <scox@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ Contribute support for Intel's iWMMXt chip - an ARM variant:
+
+ * archures.c: Add bfd_mach_arm_iWMMXt.
+ * reloc.c: Add BFD_RELOC_ARM_CP_OFF_IMM_S2.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * coff-arm.c (coff_arm_merge_private_bfd_data): Allow iWMMXt
+ object files to be linked with XScale ones.
+ (coff_arm_final_link_postscript): Update note section.
+ * coffcode.h (coff_set_arch_mach_hook): Handle note section.
+ * coffgen.c (coff_real_object_p): Call bfd_coff_set_arch_mach_hook
+ after identifying a coff binary.
+ * cpu-arm.c (processors): Add iWMMXt.
+ (arch_inf): Likewise.
+ * elf32-arm.h (arm_object_p): Handle note section.
+ (elf32_arm_merge_private_bfd_data): Allow iWMMXt object files to
+ be linked with XScale ones.
+ (elf32_arm_section_flags): New function: Set flags on note section.
+ (elf32_arm_final_write_processing): Handle note section.
+
2003-03-21 DJ Delorie <dj@redhat.com>
* elf32-xstormy16.c (elf32_xstormy16_relocate_section): Call
diff --git a/bfd/archures.c b/bfd/archures.c
index 62edda109bb..18ebb835115 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -235,6 +235,7 @@ DESCRIPTION
.#define bfd_mach_arm_5TE 9
.#define bfd_mach_arm_XScale 10
.#define bfd_mach_arm_ep9312 11
+.#define bfd_mach_arm_iWMMXt 12
. bfd_arch_ns32k, {* National Semiconductors ns32000 *}
. bfd_arch_w65, {* WDC 65816 *}
. bfd_arch_tic30, {* Texas Instruments TMS320C30 *}
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 2385c409a5c..8960f66df34 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1691,6 +1691,7 @@ enum bfd_architecture
#define bfd_mach_arm_5TE 9
#define bfd_mach_arm_XScale 10
#define bfd_mach_arm_ep9312 11
+#define bfd_mach_arm_iWMMXt 12
bfd_arch_ns32k, /* National Semiconductors ns32000 */
bfd_arch_w65, /* WDC 65816 */
bfd_arch_tic30, /* Texas Instruments TMS320C30 */
@@ -2563,6 +2564,7 @@ field in the instruction. */
BFD_RELOC_ARM_SWI,
BFD_RELOC_ARM_MULTI,
BFD_RELOC_ARM_CP_OFF_IMM,
+ BFD_RELOC_ARM_CP_OFF_IMM_S2,
BFD_RELOC_ARM_ADR_IMM,
BFD_RELOC_ARM_LDR_IMM,
BFD_RELOC_ARM_LITERAL,
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index 2fadcbef557..24015049826 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -2240,6 +2240,25 @@ coff_arm_merge_private_bfd_data (ibfd, obfd)
if (ibfd == obfd)
return TRUE;
+ if (bfd_get_mach (obfd) && bfd_get_mach (obfd) != bfd_get_mach (ibfd))
+ {
+ /* For now, allow an output file type of 'xscale' if the
+ input file type is 'iWMMXt'. This means that we will
+ not have to build an entire iWMMXt enabled set of libraries
+ just to test a iWMMXt enabled binary. Change the output
+ type to iWMMXt though. Similarly allow 'xscale' binaries
+ to be linked into a 'iWMMXt' output binary. */
+ if ( bfd_get_mach (obfd) == bfd_mach_arm_XScale
+ && bfd_get_mach (ibfd) == bfd_mach_arm_iWMMXt)
+ bfd_set_arch_mach (obfd, bfd_get_arch (obfd), bfd_mach_arm_iWMMXt);
+ else if ( bfd_get_mach (ibfd) != bfd_mach_arm_XScale
+ || bfd_get_mach (obfd) != bfd_mach_arm_iWMMXt)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+ }
+
/* If the two formats are different we cannot merge anything.
This is not an error, since it is permissable to change the
input and output formats. */
@@ -2584,6 +2603,44 @@ coff_arm_final_link_postscript (abfd, pfinfo)
globals->bfd_of_glue_owner->output_has_begun = TRUE;
}
+ {
+ asection * arm_arch_section;
+
+ /* Look for a .note section. If one is present check
+ the machine number encoded in it, and set it to the current
+ machine number if it is different. This allows XScale and
+ iWMMXt binaries to be merged and the resulting output to be set
+ to iWMMXt, even if the first input file had an XScale .note. */
+
+ arm_arch_section = bfd_get_section_by_name (abfd, ".note");
+
+ if (arm_arch_section != NULL)
+ {
+ char buffer [4];
+
+ if (bfd_get_section_contents (abfd, arm_arch_section, buffer,
+ (file_ptr) 0, sizeof buffer))
+ {
+ unsigned long arm_mach;
+
+ /* We have to extract the value this way to allow for a
+ host whose endian-ness is different from the target. */
+ arm_mach = bfd_get_32 (abfd, buffer);
+
+ if (arm_mach != bfd_get_mach (abfd))
+ {
+ bfd_put_32 (abfd, bfd_get_mach (abfd), buffer);
+
+ if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
+ (file_ptr) 0, sizeof buffer))
+ (*_bfd_error_handler)
+ (_("warning: unable to update contents of .note section in %s"),
+ bfd_get_filename (abfd));
+ }
+ }
+ }
+ }
+
return TRUE;
}
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index ee50a10993c..da8121fd77f 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1899,6 +1899,27 @@ coff_set_arch_mach_hook (abfd, filehdr)
currently the XScale. */
case F_ARM_5: machine = bfd_mach_arm_XScale; break;
}
+
+ {
+ asection * arm_arch_section;
+
+ arm_arch_section = bfd_get_section_by_name (abfd, ".note");
+
+ if (arm_arch_section)
+ {
+ bfd_byte buffer [4];
+
+ if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
+ (file_ptr) 0, sizeof buffer))
+ (*_bfd_error_handler)
+ (_("%s: warning: unable to retrieve .note section from %s"),
+ bfd_get_filename (abfd));
+
+ /* We have to extract the value this way to allow for a
+ host whose endian-ness is different from the target. */
+ machine = bfd_get_32 (abfd, buffer);
+ }
+ }
break;
#endif
#ifdef MC68MAGIC
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index c905ab17eec..a3e3eecb413 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -226,7 +226,7 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a)
if (! bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f))
goto fail;
- /* Now copy data as required; construct all asections etc */
+ /* Now copy data as required; construct all asections etc. */
if (nscns != 0)
{
unsigned int i;
@@ -241,6 +241,7 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a)
}
}
+ bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f);
/* make_abs_section (abfd); */
return abfd->xvec;
diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c
index 923c2500afe..eb3011d7d29 100644
--- a/bfd/cpu-arm.c
+++ b/bfd/cpu-arm.c
@@ -96,7 +96,8 @@ processors[] =
{ bfd_mach_arm_4, "strongarm110" },
{ bfd_mach_arm_4, "strongarm1100" },
{ bfd_mach_arm_XScale, "xscale" },
- { bfd_mach_arm_ep9312, "ep9312" }
+ { bfd_mach_arm_ep9312, "ep9312" },
+ { bfd_mach_arm_iWMMXt, "iwmmxt" }
};
static bfd_boolean
@@ -142,7 +143,8 @@ static const bfd_arch_info_type arch_info_struct[] =
N (bfd_mach_arm_5T, "armv5t", FALSE, & arch_info_struct[8]),
N (bfd_mach_arm_5TE, "armv5te", FALSE, & arch_info_struct[9]),
N (bfd_mach_arm_XScale, "xscale", FALSE, & arch_info_struct[10]),
- N (bfd_mach_arm_ep9312, "ep9312", FALSE, NULL)
+ N (bfd_mach_arm_ep9312, "ep9312", FALSE, & arch_info_struct[11]),
+ N (bfd_mach_arm_iWMMXt,"iwmmxt", FALSE, NULL)
};
const bfd_arch_info_type bfd_arm_arch =
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index 509b4815574..417284b3169 100644
--- a/bfd/elf32-arm.h
+++ b/bfd/elf32-arm.h
@@ -2119,10 +2119,43 @@ static bfd_boolean
elf32_arm_object_p (abfd)
bfd *abfd;
{
- /* XXX - we ought to examine a .note section here. */
+ asection * arm_arch_section;
- if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
- bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312);
+ arm_arch_section = bfd_get_section_by_name (abfd, ARM_NOTE_SECTION);
+
+ if (arm_arch_section)
+ {
+ char buffer [4];
+ unsigned long arm_mach;
+
+ if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
+ (file_ptr) 0, sizeof buffer))
+ (*_bfd_error_handler)
+ (_("%s: warning: unable to retrieve %s section from %s"),
+ ARM_NOTE_SECTION, bfd_get_filename (abfd));
+ else
+ {
+ /* We have to extract the value this way to allow for a
+ host whose endian-ness is different from the target. */
+ arm_mach = bfd_get_32 (abfd, buffer);
+ bfd_default_set_arch_mach (abfd, bfd_arch_arm, arm_mach);
+
+ if (bfd_get_arch (abfd) == bfd_arch_arm)
+ return TRUE;
+
+ /* If the set failed for some reason, do not leave the architecture
+ type as 0 (unknown), but issue a warning message and force it to
+ be set to bfd_arch_arm. */
+ (*_bfd_error_handler)
+ (_("%s: warning: unrecognized ARM machine number: %x"),
+ bfd_get_filename (abfd), arm_mach);
+ }
+ }
+ else
+ {
+ if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
+ bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312);
+ }
return TRUE;
}
@@ -2263,6 +2296,25 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
return TRUE;
}
+ if (bfd_get_mach (obfd) && bfd_get_mach (obfd) != bfd_get_mach (ibfd))
+ {
+ /* For now, allow an output file type of 'xscale' if the
+ input file type is 'iWMMXt'. This means that we will
+ not have to build an entire iWMMXt enabled set of libraries
+ just to test a iWMMXt enabled binary. Change the output
+ type to iWMMXt though. Similarly allow 'xscale' binaries
+ to be linked into a 'iWMMXt' output binary. */
+ if ( bfd_get_mach (obfd) == bfd_mach_arm_XScale
+ && bfd_get_mach (ibfd) == bfd_mach_arm_iWMMXt)
+ bfd_set_arch_mach (obfd, bfd_get_arch (obfd), bfd_mach_arm_iWMMXt);
+ else if ( bfd_get_mach (ibfd) != bfd_mach_arm_XScale
+ || bfd_get_mach (obfd) != bfd_mach_arm_iWMMXt)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+ }
+
/* Identical flags must be compatible. */
if (in_flags == out_flags)
return TRUE;
@@ -3660,6 +3712,65 @@ elf32_arm_reloc_type_class (rela)
}
}
+static bfd_boolean elf32_arm_section_flags PARAMS ((flagword *, Elf_Internal_Shdr *));
+static void elf32_arm_final_write_processing PARAMS ((bfd *, bfd_boolean));
+
+/* Set the right machine number for an Arm ELF file. */
+
+static bfd_boolean
+elf32_arm_section_flags (flags, hdr)
+ flagword *flags;
+ Elf_Internal_Shdr *hdr;
+{
+ if (hdr->sh_type == SHT_NOTE)
+ *flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS;
+
+ return TRUE;
+}
+
+void
+elf32_arm_final_write_processing (abfd, linker)
+ bfd *abfd;
+ bfd_boolean linker ATTRIBUTE_UNUSED;
+{
+ asection * arm_arch_section;
+ char buffer [4];
+ unsigned long arm_mach;
+
+ /* Look for a .note.arm.ident section. If one is present check
+ the machine number encoded in it, and set it to the current
+ machine number if it is different. This allows XScale and
+ iWMMXt binaries to be merged and the resulting output to be set
+ to iWMMXt, even if the first input file had an XScale .note. */
+
+ arm_arch_section = bfd_get_section_by_name (abfd, ARM_NOTE_SECTION);
+
+ if (arm_arch_section == NULL)
+ return;
+
+ if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
+ (file_ptr) 0, sizeof buffer))
+ /* If the ident section does not exist then just skip this check. */
+ return;
+
+ /* We have to extract the value this way to allow for a
+ host whose endian-ness is different from the target. */
+ arm_mach = bfd_get_32 (abfd, buffer);
+
+ if (arm_mach == bfd_get_mach (abfd))
+ return;
+
+ bfd_put_32 (abfd, bfd_get_mach (abfd), buffer);
+
+ if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
+ (file_ptr) 0, sizeof buffer))
+ (*_bfd_error_handler)
+ (_("warning: unable to update contents of %s section in %s"),
+ ARM_NOTE_SECTION, bfd_get_filename (abfd));
+
+ return;
+}
+
#define ELF_ARCH bfd_arch_arm
#define ELF_MACHINE_CODE EM_ARM
#define ELF_MAXPAGESIZE 0x8000
@@ -3685,6 +3796,8 @@ elf32_arm_reloc_type_class (rela)
#define elf_backend_post_process_headers elf32_arm_post_process_headers
#define elf_backend_reloc_type_class elf32_arm_reloc_type_class
#define elf_backend_object_p elf32_arm_object_p
+#define elf_backend_section_flags elf32_arm_section_flags
+#define elf_backend_final_write_processing elf32_arm_final_write_processing
#define elf_backend_can_gc_sections 1
#define elf_backend_plt_readonly 1
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 222b23dcb5d..df2ba3e3f97 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1043,6 +1043,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARM_SWI",
"BFD_RELOC_ARM_MULTI",
"BFD_RELOC_ARM_CP_OFF_IMM",
+ "BFD_RELOC_ARM_CP_OFF_IMM_S2",
"BFD_RELOC_ARM_ADR_IMM",
"BFD_RELOC_ARM_LDR_IMM",
"BFD_RELOC_ARM_LITERAL",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 9f8a952c591..f4a33218022 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2519,6 +2519,8 @@ ENUMX
ENUMX
BFD_RELOC_ARM_CP_OFF_IMM
ENUMX
+ BFD_RELOC_ARM_CP_OFF_IMM_S2
+ENUMX
BFD_RELOC_ARM_ADR_IMM
ENUMX
BFD_RELOC_ARM_LDR_IMM
diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog
index b2eec4cbe93..be6154d21c1 100644
--- a/include/coff/ChangeLog
+++ b/include/coff/ChangeLog
@@ -1,3 +1,10 @@
+2003-03-25 Stan Cox <scox@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ Contribute support for Intel's iWMMXt chip - an ARM variant:
+
+ * arm.h (ARM_NOTE_SECTION): Define.
+
2002-11-30 Alan Modra <amodra@bigpond.net.au>
* ecoff.h: Replace boolean with bfd_boolean.
diff --git a/include/coff/arm.h b/include/coff/arm.h
index bcfdcbe4784..8b90228ca98 100644
--- a/include/coff/arm.h
+++ b/include/coff/arm.h
@@ -124,3 +124,5 @@ struct external_reloc
#define RELOC struct external_reloc
#define RELSZ 14
#endif
+
+#define ARM_NOTE_SECTION ".note"
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index e87cdd2e045..5411f769169 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,4 +1,11 @@
-Mon Mar 3 20:35:58 2003 J"orn Rennecke <joern.rennecke@superh.com>
+2003-03-25 Stan Cox <scox@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ Contribute support for Intel's iWMMXt chip - an ARM variant:
+
+ * arm.h (ARM_NOTE_SECTION): Define.
+
+2003-03-03 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (EF_SH_MERGE_MACH): Make sure SH2E & SH3/SH3E merge to SH3E,
and SH2E & SH4 merge to SH4, not SH2E.
diff --git a/include/elf/arm.h b/include/elf/arm.h
index 534701753c4..3b3f8d0e235 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -140,4 +140,7 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
RELOC_NUMBER (R_ARM_RBASE, 255)
END_RELOC_NUMBERS (R_ARM_max)
+/* The name of the note section used to identify arm variants. */
+#define ARM_NOTE_SECTION ".note.arm.ident"
+
#endif /* _ELF_ARM_H */
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index d3162797302..b1338964e53 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,14 @@
+2003-03-25 Stan Cox <scox@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ Contribute support for Intel's iWMMXt chip - an ARM variant:
+
+ * arm-dis.c (regnames): Add iWMMXt register names.
+ (set_iwmmxt_regnames): New function.
+ (print_insn_arm): Handle iWMMXt formatters.
+ * arm-opc.h: Document iWMMXt formatters.
+ (arm_opcod): Add iWMMXt instructions.
+
2003-03-22 Doug Evans <dje@sebabeach.org>
* i386-dis.c (dis386): Recognize icebp (0xf1).
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 62a2a39ab62..8fb970245dc 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -1,24 +1,24 @@
/* Instruction printing code for the ARM
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
Modification by James G. Smith (jsmith@cygnus.co.uk)
-This file is part of libopcodes.
+ This file is part of libopcodes.
-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 2 of the License, or (at your option)
-any later version.
+ 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 2 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.
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "sysdep.h"
#include "dis-asm.h"
@@ -70,7 +70,21 @@ static arm_regname regnames[] =
{ "atpcs", "Select register names used in the ATPCS",
{ "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
{ "special-atpcs", "Select special register names used in the ATPCS",
- { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}
+ { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
+ { "iwmmxt_regnames", "Select register names used on the Intel(r) Wireless MMX(tm) technology coprocessor",
+ { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
+ { "iwmmxt_Cregnames", "Select control register names used on the Intel(r) Wireless MMX(tm) technology coprocessor",
+ {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
+};
+
+static char * iwmmxt_wwnames[] =
+{"b", "h", "w", "d"};
+
+static char * iwmmxt_wwssnames[] =
+{"b", "bus", "b", "bss",
+ "h", "hus", "h", "hss",
+ "w", "wus", "w", "wss",
+ "d", "dus", "d", "dss"
};
/* Default to GCC register name set. */
@@ -98,11 +112,15 @@ static void parse_disassembler_options
PARAMS ((char *));
static int print_insn
PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
-int get_arm_regname_num_options (void);
-int set_arm_regname_option (int option);
-int get_arm_regnames (int option, const char **setname,
- const char **setdescription,
- const char ***register_names);
+static int set_iwmmxt_regnames
+ PARAMS ((void));
+
+int get_arm_regname_num_options
+ PARAMS ((void));
+int set_arm_regname_option
+ PARAMS ((int));
+int get_arm_regnames
+ PARAMS ((int, const char **, const char **, const char ***));
/* Functions. */
int
@@ -167,6 +185,24 @@ arm_decode_shift (given, func, stream)
}
}
+static int
+set_iwmmxt_regnames ()
+{
+ const char * setname;
+ const char * setdesc;
+ const char ** regnames;
+ int iwmmxt_regnames = 0;
+ int num_regnames = get_arm_regname_num_options ();
+
+ get_arm_regnames (iwmmxt_regnames, &setname,
+ &setdesc, &regnames);
+ while ((strcmp ("iwmmxt_regnames", setname))
+ && (iwmmxt_regnames < num_regnames))
+ get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
+
+ return iwmmxt_regnames;
+}
+
/* Print one instruction from PC on INFO->STREAM.
Return the size of the instruction (always 4 on ARM). */
@@ -179,9 +215,15 @@ print_insn_arm (pc, info, given)
const struct arm_opcode *insn;
void *stream = info->stream;
fprintf_ftype func = info->fprintf_func;
+ static int iwmmxt_regnames = 0;
for (insn = arm_opcodes; insn->assembler; insn++)
{
+ if (insn->value == FIRST_IWMMXT_INSN
+ && info->mach != bfd_mach_arm_XScale
+ && info->mach != bfd_mach_arm_iWMMXt)
+ insn = insn + IWMMXT_INSN_COUNT;
+
if ((given & insn->mask) == insn->value)
{
char * c;
@@ -629,6 +671,63 @@ print_insn_arm (pc, info, given)
func (stream, "f%d", reg);
}
break;
+
+ case 'w':
+ {
+ long reg;
+
+ if (bitstart != bitend)
+ {
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ if (bitend - bitstart == 1)
+ func (stream, "%s", iwmmxt_wwnames[reg]);
+ else
+ func (stream, "%s", iwmmxt_wwssnames[reg]);
+ }
+ else
+ {
+ reg = (((given >> 8) & 0x1) |
+ ((given >> 22) & 0x1));
+ func (stream, "%s", iwmmxt_wwnames[reg]);
+ }
+ }
+ break;
+
+ case 'g':
+ {
+ long reg;
+ int current_regnames;
+
+ if (! iwmmxt_regnames)
+ iwmmxt_regnames = set_iwmmxt_regnames ();
+ current_regnames = set_arm_regname_option
+ (iwmmxt_regnames);
+
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ func (stream, "%s", arm_regnames[reg]);
+ set_arm_regname_option (current_regnames);
+ }
+ break;
+
+ case 'G':
+ {
+ long reg;
+ int current_regnames;
+
+ if (! iwmmxt_regnames)
+ iwmmxt_regnames = set_iwmmxt_regnames ();
+ current_regnames = set_arm_regname_option
+ (iwmmxt_regnames + 1);
+
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ func (stream, "%s", arm_regnames[reg]);
+ set_arm_regname_option (current_regnames);
+ }
+ break;
+
default:
abort ();
}
@@ -734,6 +833,54 @@ print_insn_arm (pc, info, given)
}
break;
+ case 'L':
+ switch (given & 0x00400100)
+ {
+ case 0x00000000: func (stream, "b"); break;
+ case 0x00400000: func (stream, "h"); break;
+ case 0x00000100: func (stream, "w"); break;
+ case 0x00400100: func (stream, "d"); break;
+ default:
+ break;
+ }
+ break;
+
+ case 'Z':
+ {
+ int value;
+ /* given (20, 23) | given (0, 3) */
+ value = ((given >> 16) & 0xf0) | (given & 0xf);
+ func (stream, "%d", value);
+ }
+ break;
+
+ case 'l':
+ /* This is like the 'A' operator, except that if
+ the width field "M" is zero, then the offset is
+ *not* multiplied by four. */
+ {
+ int offset = given & 0xff;
+ int multiplier = (given & 0x00000100) ? 4 : 1;
+
+ func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+
+ if (offset)
+ {
+ if ((given & 0x01000000) != 0)
+ func (stream, ", %s#%d]%s",
+ ((given & 0x00800000) == 0 ? "-" : ""),
+ offset * multiplier,
+ ((given & 0x00200000) != 0 ? "!" : ""));
+ else
+ func (stream, "], %s#%d",
+ ((given & 0x00800000) == 0 ? "-" : ""),
+ offset * multiplier);
+ }
+ else
+ func (stream, "]");
+ }
+ break;
+
default:
abort ();
}
diff --git a/opcodes/arm-opc.h b/opcodes/arm-opc.h
index 213d4f034de..233a8303fea 100644
--- a/opcodes/arm-opc.h
+++ b/opcodes/arm-opc.h
@@ -1,6 +1,6 @@
/* Opcode table for the ARM.
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -60,6 +60,13 @@ struct thumb_opcode
%m print register mask for ldm/stm instruction
%C print the PSR sub type.
%F print the COUNT field of a LFM/SFM instruction.
+IWMMXT specific format options:
+ %<bitfield>g print as an iWMMXt 64-bit register
+ %<bitfield>G print as an iWMMXt general purpose or control register
+ %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
+ %Z print the Immediate of a WSHUFH instruction.
+ %L print as an iWMMXt N/M width field.
+ %l like 'A' except use byte offsets for 'B' & 'H' versions
Thumb specific format options:
%D print Thumb register (bits 0..2 as high number if bit 7 set)
%S print Thumb register (bits 3..5 as high number if bit 6 set)
@@ -101,6 +108,59 @@ static const struct arm_opcode arm_opcodes[] =
{0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
{0xf450f000, 0xfc70f000, "pld\t%a"},
+ /* Intel(r) Wireless MMX(tm) technology instructions. */
+#define FIRST_IWMMXT_INSN 0x0e130130
+#define IWMMXT_INSN_COUNT 47
+ {0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
+ {0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
+ {0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
+ {0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
+ {0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
+ {0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
+ {0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
+ {0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
+ {0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
+ {0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
+ {0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
+ {0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
+ {0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
+ {0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
+ {0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
+ {0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
+ {0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
+ {0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
+ {0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+ {0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
+ {0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+ {0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+ {0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
+ {0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
+ {0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
+ {0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
+ {0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
+ {0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
+ {0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
+
/* V5 Instructions. */
{0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
{0xfa000000, 0xfe000000, "blx\t%B"},