summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2006-02-24 15:36:36 +0000
committerPaul Brook <paul@codesourcery.com>2006-02-24 15:36:36 +0000
commit804f24bbeb39407b12bad6944b5c1ca3dc8cede4 (patch)
treefb7ffa4f2390ade25e109f2df26036121531d830
parent5f8fec255f2ebe427c279e3546f5faf00d79fd65 (diff)
downloadgdb-804f24bbeb39407b12bad6944b5c1ca3dc8cede4.tar.gz
2006-02-24 Paul Brook <paul@codesourcery.com>
gas/ * config/arm/tc-arm.c (arm_ext_v6_notm, arm_ext_div, arm_ext_v7, arm_ext_v7a, arm_ext_v7r, arm_ext_v7m): New variables. (struct asm_barrier_opt): Define. (arm_v7m_psr_hsh, arm_barrier_opt_hsh): New variables. (parse_psr): Accept V7M psr names. (parse_barrier): New function. (enum operand_parse_code): Add OP_oBARRIER. (parse_operands): Implement OP_oBARRIER. (do_barrier): New function. (do_dbg, do_pli, do_t_barrier, do_t_dbg, do_t_div): New functions. (do_t_cpsi): Add V7M restrictions. (do_t_mrs, do_t_msr): Validate V7M variants. (md_assemble): Check for NULL variants. (v7m_psrs, barrier_opt_names): New tables. (insns): Add V7 instructions. Mark V6 instructions absent from V7M. (md_begin): Initialize arm_v7m_psr_hsh and arm_barrier_opt_hsh. (arm_cpu_option_table): Add Cortex-M3, R4 and A8. (arm_arch_option_table): Add armv7, armv7a, armv7r and armv7m. (struct cpu_arch_ver_table): Define. (cpu_arch_ver): New. (aeabi_set_public_attributes): Use cpu_arch_ver. Set Tag_CPU_arch_profile. * doc/c-arm.texi: Document new cpu and arch options. gas/testsuite/ * gas/arm/thumb32.d: Fix expected msr and mrs output. * gas/arm/arch7.d: New test. * gas/arm/arch7.s: New test. * gas/arm/arch7m-bad.l: New test. * gas/arm/arch7m-bad.d: New test. * gas/arm/arch7m-bad.s: New test. include/opcode/ * arm.h: Add V7 feature bits. opcodes/ * arm-dis.c (arm_opcodes): Add V7 instructions. (thumb32_opcodes): Ditto. Handle V7M MSR/MRS variants. (print_arm_address): New function. (print_insn_arm): Use it. Add 'P' and 'U' cases. (psr_name): New function. (print_insn_thumb32): Add 'U', 'C' and 'D' cases.
-rw-r--r--include/opcode/ChangeLog4
-rw-r--r--include/opcode/arm.h31
-rw-r--r--opcodes/ChangeLog9
-rw-r--r--opcodes/arm-dis.c277
4 files changed, 233 insertions, 88 deletions
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index fedd6387505..76b797834bf 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,7 @@
+2006-02-24 Paul Brook <paul@codesourcery.com>
+
+ * arm.h: Add V7 feature bits.
+
2006-02-23 H.J. Lu <hongjiu.lu@intel.com>
* ia64.h (ia64_opnd): Add IA64_OPND_IMMU5b.
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index 97312b63fb3..3260b2feaaa 100644
--- a/include/opcode/arm.h
+++ b/include/opcode/arm.h
@@ -35,6 +35,15 @@
#define ARM_EXT_V6K 0x00002000 /* ARM V6K. */
#define ARM_EXT_V6Z 0x00004000 /* ARM V6Z. */
#define ARM_EXT_V6T2 0x00008000 /* Thumb-2. */
+#define ARM_EXT_DIV 0x00010000 /* Integer division. */
+/* The 'M' in Arm V7M stands for Microcontroller.
+ On earlier architecture variants it stands for Multiply. */
+#define ARM_EXT_V5E_NOTM 0x00020000 /* Arm V5E but not Arm V7M. */
+#define ARM_EXT_V6_NOTM 0x00040000 /* Arm V6 but not Arm V7M. */
+#define ARM_EXT_V7 0x00080000 /* Arm V7. */
+#define ARM_EXT_V7A 0x00100000 /* Arm V7A. */
+#define ARM_EXT_V7R 0x00200000 /* Arm V7R. */
+#define ARM_EXT_V7M 0x00400000 /* Arm V7M. */
/* Co-processor space extensions. */
#define ARM_CEXT_XSCALE 0x00000001 /* Allow MIA etc. */
@@ -75,10 +84,18 @@
#define ARM_AEXT_V6K (ARM_AEXT_V6 | ARM_EXT_V6K)
#define ARM_AEXT_V6Z (ARM_AEXT_V6 | ARM_EXT_V6Z)
#define ARM_AEXT_V6ZK (ARM_AEXT_V6 | ARM_EXT_V6K | ARM_EXT_V6Z)
-#define ARM_AEXT_V6T2 (ARM_AEXT_V6 | ARM_EXT_V6T2)
-#define ARM_AEXT_V6KT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K)
-#define ARM_AEXT_V6ZT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6Z)
-#define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z)
+#define ARM_AEXT_V6T2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6_NOTM)
+#define ARM_AEXT_V6KT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K)
+#define ARM_AEXT_V6ZT2 (ARM_AEXT_V6T2 | ARM_EXT_V6Z)
+#define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z)
+#define ARM_AEXT_V7_ARM (ARM_AEXT_V6T2 | ARM_EXT_V7)
+#define ARM_AEXT_V7A (ARM_AEXT_V7_ARM | ARM_EXT_V7A)
+#define ARM_AEXT_V7R (ARM_AEXT_V7_ARM | ARM_EXT_V7R | ARM_EXT_DIV)
+#define ARM_AEXT_NOTM \
+ (ARM_AEXT_V4 | ARM_EXT_V5ExP | ARM_EXT_V5J | ARM_EXT_V6_NOTM)
+#define ARM_AEXT_V7M \
+ ((ARM_AEXT_V7_ARM | ARM_EXT_V7M | ARM_EXT_DIV) & ~(ARM_AEXT_NOTM))
+#define ARM_AEXT_V7 (ARM_AEXT_V7A & ARM_AEXT_V7R & ARM_AEXT_V7M)
/* Processors with specific extensions in the co-processor space. */
#define ARM_ARCH_XSCALE ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE)
@@ -130,13 +147,17 @@
#define ARM_ARCH_V6KT2 ARM_FEATURE (ARM_AEXT_V6KT2, 0)
#define ARM_ARCH_V6ZT2 ARM_FEATURE (ARM_AEXT_V6ZT2, 0)
#define ARM_ARCH_V6ZKT2 ARM_FEATURE (ARM_AEXT_V6ZKT2, 0)
+#define ARM_ARCH_V7 ARM_FEATURE (ARM_AEXT_V7, 0)
+#define ARM_ARCH_V7A ARM_FEATURE (ARM_AEXT_V7A, 0)
+#define ARM_ARCH_V7R ARM_FEATURE (ARM_AEXT_V7R, 0)
+#define ARM_ARCH_V7M ARM_FEATURE (ARM_AEXT_V7M, 0)
/* Some useful combinations: */
#define ARM_ARCH_NONE ARM_FEATURE (0, 0)
#define FPU_NONE ARM_FEATURE (0, 0)
#define ARM_ANY ARM_FEATURE (-1, 0) /* Any basic core. */
#define FPU_ANY_HARD ARM_FEATURE (0, FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
-#define ARM_ARCH_THUMB2 ARM_FEATURE (ARM_EXT_V6T2, 0)
+#define ARM_ARCH_THUMB2 ARM_FEATURE (ARM_EXT_V6T2 | ARM_EXT_V7 | ARM_EXT_V7A | ARM_EXT_V7R | ARM_EXT_V7M | ARM_EXT_DIV, 0)
/* There are too many feature bits to fit in a single word, so use a
structure. For simplicity we put all core features in one word and
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index a8960dbaa61..6aad1942616 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,12 @@
+2006-02-24 Paul Brook <paul@codesourcery.com>
+
+ * arm-dis.c (arm_opcodes): Add V7 instructions.
+ (thumb32_opcodes): Ditto. Handle V7M MSR/MRS variants.
+ (print_arm_address): New function.
+ (print_insn_arm): Use it. Add 'P' and 'U' cases.
+ (psr_name): New function.
+ (print_insn_thumb32): Add 'U', 'C' and 'D' cases.
+
2006-02-23 H.J. Lu <hongjiu.lu@intel.com>
* ia64-opc-i.c (bXc): New.
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index fb3cb77bc4a..b5167e9b6f2 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -402,6 +402,8 @@ static const struct opcode32 coprocessor_opcodes[] =
%t print 't' iff bit 21 set and bit 24 clear
%B print arm BLX(1) destination
%C print the PSR sub type.
+ %U print barrier type.
+ %P print address for pli instruction.
%<bitfield>r print as an ARM register
%<bitfield>d print the bitfield in decimal
@@ -428,6 +430,13 @@ static const struct opcode32 arm_opcodes[] =
{ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
{ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
+ /* V7 instructions. */
+ {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
+ {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
+ {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
+ {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
+ {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
+
/* ARM V6T2 instructions. */
{ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
{ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
@@ -827,6 +836,8 @@ static const struct opcode16 thumb_opcodes[] =
%B print an unconditional branch offset
%s print the shift field of an SSAT instruction
%R print the rotation field of an SXT instruction
+ %U print barrier type.
+ %P print address for pli instruction.
%<bitfield>d print bitfield in decimal
%<bitfield>W print bitfield*4 in decimal
@@ -847,6 +858,15 @@ static const struct opcode16 thumb_opcodes[] =
makes heavy use of special-case bit patterns. */
static const struct opcode32 thumb32_opcodes[] =
{
+ /* V7 instructions. */
+ {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"},
+ {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"},
+ {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"},
+ {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"},
+ {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"},
+ {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"},
+ {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"},
+
/* Instructions defined in the basic V6T2 set. */
{ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
{ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
@@ -861,14 +881,14 @@ static const struct opcode32 thumb32_opcodes[] =
{ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
{ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
{ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
- {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff0ff, "mrs\t%8-11r, %20?CSPSR"},
+ {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"},
{ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
{ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
{ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"},
{ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
{ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
{ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
- {ARM_EXT_V6T2, 0xf3808000, 0xffe0f0ff, "msr\t%20?CSPSR_%8'c%9'x%10's%11'f, %16-19r"},
+ {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"},
{ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
@@ -1602,6 +1622,96 @@ print_insn_coprocessor (struct disassemble_info *info, long given,
return FALSE;
}
+static void
+print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
+{
+ void *stream = info->stream;
+ fprintf_ftype func = info->fprintf_func;
+
+ if (((given & 0x000f0000) == 0x000f0000)
+ && ((given & 0x02000000) == 0))
+ {
+ int offset = given & 0xfff;
+
+ func (stream, "[pc");
+
+ if (given & 0x01000000)
+ {
+ if ((given & 0x00800000) == 0)
+ offset = - offset;
+
+ /* Pre-indexed. */
+ func (stream, ", #%d]", offset);
+
+ offset += pc + 8;
+
+ /* Cope with the possibility of write-back
+ being used. Probably a very dangerous thing
+ for the programmer to do, but who are we to
+ argue ? */
+ if (given & 0x00200000)
+ func (stream, "!");
+ }
+ else
+ {
+ /* Post indexed. */
+ func (stream, "], #%d", offset);
+
+ /* ie ignore the offset. */
+ offset = pc + 8;
+ }
+
+ func (stream, "\t; ");
+ info->print_address_func (offset, info);
+ }
+ else
+ {
+ func (stream, "[%s",
+ arm_regnames[(given >> 16) & 0xf]);
+ if ((given & 0x01000000) != 0)
+ {
+ if ((given & 0x02000000) == 0)
+ {
+ int offset = given & 0xfff;
+ if (offset)
+ func (stream, ", #%s%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ }
+ else
+ {
+ func (stream, ", %s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""));
+ arm_decode_shift (given, func, stream);
+ }
+
+ func (stream, "]%s",
+ ((given & 0x00200000) != 0) ? "!" : "");
+ }
+ else
+ {
+ if ((given & 0x02000000) == 0)
+ {
+ int offset = given & 0xfff;
+ if (offset)
+ func (stream, "], #%s%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ else
+ func (stream, "]");
+ }
+ else
+ {
+ func (stream, "], %s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""));
+ arm_decode_shift (given, func, stream);
+ }
+ }
+ }
+}
+
/* Print one ARM instruction from PC on INFO->STREAM. */
static void
@@ -1642,88 +1752,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
break;
case 'a':
- if (((given & 0x000f0000) == 0x000f0000)
- && ((given & 0x02000000) == 0))
- {
- int offset = given & 0xfff;
-
- func (stream, "[pc");
-
- if (given & 0x01000000)
- {
- if ((given & 0x00800000) == 0)
- offset = - offset;
-
- /* Pre-indexed. */
- func (stream, ", #%d]", offset);
-
- offset += pc + 8;
-
- /* Cope with the possibility of write-back
- being used. Probably a very dangerous thing
- for the programmer to do, but who are we to
- argue ? */
- if (given & 0x00200000)
- func (stream, "!");
- }
- else
- {
- /* Post indexed. */
- func (stream, "], #%d", offset);
-
- /* ie ignore the offset. */
- offset = pc + 8;
- }
-
- func (stream, "\t; ");
- info->print_address_func (offset, info);
- }
- else
- {
- func (stream, "[%s",
- arm_regnames[(given >> 16) & 0xf]);
- if ((given & 0x01000000) != 0)
- {
- if ((given & 0x02000000) == 0)
- {
- int offset = given & 0xfff;
- if (offset)
- func (stream, ", #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
- }
- else
- {
- func (stream, ", %s",
- (((given & 0x00800000) == 0)
- ? "-" : ""));
- arm_decode_shift (given, func, stream);
- }
+ print_arm_address (pc, info, given);
+ break;
- func (stream, "]%s",
- ((given & 0x00200000) != 0) ? "!" : "");
- }
- else
- {
- if ((given & 0x02000000) == 0)
- {
- int offset = given & 0xfff;
- if (offset)
- func (stream, "], #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
- else
- func (stream, "]");
- }
- else
- {
- func (stream, "], %s",
- (((given & 0x00800000) == 0)
- ? "-" : ""));
- arm_decode_shift (given, func, stream);
- }
- }
- }
+ case 'P':
+ /* Set P address bit and use normal address
+ printing routine. */
+ print_arm_address (pc, info, given | (1 << 24));
break;
case 's':
@@ -1913,6 +1948,19 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
func (stream, "c");
break;
+ case 'U':
+ switch (given & 0xf)
+ {
+ case 0xf: func(stream, "sy"); break;
+ case 0x7: func(stream, "un"); break;
+ case 0xe: func(stream, "st"); break;
+ case 0x6: func(stream, "unst"); break;
+ default:
+ func(stream, "#%d", (int)given & 0xf);
+ break;
+ }
+ break;
+
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
@@ -2292,6 +2340,30 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
abort ();
}
+/* Return the name of an V7M special register. */
+static const char *
+psr_name (int regno)
+{
+ switch (regno)
+ {
+ case 0: return "APSR";
+ case 1: return "IAPSR";
+ case 2: return "EAPSR";
+ case 3: return "PSR";
+ case 5: return "IPSR";
+ case 6: return "EPSR";
+ case 7: return "IEPSR";
+ case 8: return "MSP";
+ case 9: return "PSP";
+ case 16: return "PRIMASK";
+ case 17: return "BASEPRI";
+ case 18: return "BASEPRI_MASK";
+ case 19: return "FAULTMASK";
+ case 20: return "CONTROL";
+ default: return "<unknown>";
+ }
+}
+
/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
static void
@@ -2638,6 +2710,45 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
}
break;
+ case 'U':
+ switch (given & 0xf)
+ {
+ case 0xf: func(stream, "sy"); break;
+ case 0x7: func(stream, "un"); break;
+ case 0xe: func(stream, "st"); break;
+ case 0x6: func(stream, "unst"); break;
+ default:
+ func(stream, "#%d", (int)given & 0xf);
+ break;
+ }
+ break;
+
+ case 'C':
+ if ((given & 0xff) == 0)
+ {
+ func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
+ if (given & 0x800)
+ func (stream, "f");
+ if (given & 0x400)
+ func (stream, "s");
+ if (given & 0x200)
+ func (stream, "x");
+ if (given & 0x100)
+ func (stream, "c");
+ }
+ else
+ {
+ func (stream, psr_name (given & 0xff));
+ }
+ break;
+
+ case 'D':
+ if ((given & 0xff) == 0)
+ func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
+ else
+ func (stream, psr_name (given & 0xff));
+ break;
+
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{