ARM v6T2 - flags, ARM-instruction disassembly

Zack Weinberg zack@codesourcery.com
Sat Mar 12 07:03:00 GMT 2005


ARMv6T2's main claim to fame is the extensive revisions to the Thumb
instruction set, but it also adds a small number of plain old ARM
instructions.  This patch adds ARM_EXT_ and ARM_ARCH_ macros for v6T2,
alone and in combination with the other v6 extensions, and
disassembler support for the new ARM instructions.  If accepted,
assembler support will follow in short order.

There is also a tangential tweak: I changed the disassembly loop so
that an instruction whose condition field is all-bits-one will only
match an opcode table entry whose mask covers the entire condition
field.  This allows us not to have to worry about the relative order
of the opcode table entries for an "unconditional instruction space"
instruction and the corresponding "ordinary" instruction.

This consumes the last unused bit of the "basic core" portion of the
masks in opcode/arm.h.  There are several more core-instruction-set
extensions in the pipeline, so now would be a good time to discuss
what to do to get more space.  I see three alternatives:

1) Steal bits from the co-processor space, which is currently using
   only three of its eight bits.  Probably safe, but not very future
   proof.

2) Drop support for obsolete cores, e.g. V1 through V3 and possibly
   also the xM and xP variants of V4 and V5.  I don't know how many
   people are still out there using them, though.

3) Expand the variables that hold these values, to give us more room.
   Lots of work, but mostly mechanical, and would make the problem go
   away for the foreseeable future.

zw

include:
        * opcode/arm.h: Adjust comments for ARM_EXT_V4T and ARM_EXT_V5T.
        Add ARM_EXT_V6T2, ARM_ARCH_V6T2, ARM_ARCH_V6KT2, ARM_ARCH_V6ZT2,
        and ARM_ARCH_V6ZKT2.
opcodes:
        * arm-dis.c (arm_opcodes): Document %E and %V.
        Add entries for v6T2 ARM instructions:
        bfc bfi mls strht ldrht ldrsht ldrsbt movw movt rbit ubfx sbfx.
        (print_insn_arm): Add support for %E and %V.

===================================================================
Index: include/opcode/arm.h
--- include/opcode/arm.h	2005-02-08 11:35:26.000000000 -0800
+++ include/opcode/arm.h	2005-03-11 15:24:13.000000000 -0800
@@ -25,15 +25,16 @@
 #define ARM_EXT_V3	 0x00000008	/* MSR MRS.                */
 #define ARM_EXT_V3M	 0x00000010	/* Allow long multiplies.  */
 #define ARM_EXT_V4	 0x00000020	/* Allow half word loads.  */
-#define ARM_EXT_V4T	 0x00000040	/* Thumb v1.               */
+#define ARM_EXT_V4T	 0x00000040	/* Thumb.                  */
 #define ARM_EXT_V5	 0x00000080	/* Allow CLZ, etc.         */
-#define ARM_EXT_V5T	 0x00000100	/* Thumb v2.               */
+#define ARM_EXT_V5T	 0x00000100	/* Improved interworking.  */
 #define ARM_EXT_V5ExP	 0x00000200	/* DSP core set.           */
 #define ARM_EXT_V5E	 0x00000400	/* DSP Double transfers.   */
 #define ARM_EXT_V5J	 0x00000800	/* Jazelle extension.	   */
 #define ARM_EXT_V6       0x00001000     /* ARM V6.                 */
 #define ARM_EXT_V6K      0x00002000     /* ARM V6K.                */
 #define ARM_EXT_V6Z      0x00004000     /* ARM V6Z.                */
+#define ARM_EXT_V6T2	 0x00008000	/* Thumb-2.                */
 
 /* Co-processor space extensions.  */
 #define ARM_CEXT_XSCALE   0x00800000	/* Allow MIA etc.          */
@@ -65,6 +66,10 @@
 #define ARM_ARCH_V6K    (ARM_ARCH_V6    | ARM_EXT_V6K)
 #define ARM_ARCH_V6Z    (ARM_ARCH_V6    | ARM_EXT_V6Z)
 #define ARM_ARCH_V6ZK   (ARM_ARCH_V6    | ARM_EXT_V6K | ARM_EXT_V6Z)
+#define ARM_ARCH_V6T2   (ARM_ARCH_V6    | ARM_EXT_V6T2)
+#define ARM_ARCH_V6KT2  (ARM_ARCH_V6    | ARM_EXT_V6T2 | ARM_EXT_V6K)
+#define ARM_ARCH_V6ZT2  (ARM_ARCH_V6    | ARM_EXT_V6T2 | ARM_EXT_V6Z)
+#define ARM_ARCH_V6ZKT2 (ARM_ARCH_V6    | ARM_EXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z)
 
 /* Processors with specific extensions in the co-processor space.  */
 #define ARM_ARCH_XSCALE	(ARM_ARCH_V5TE	| ARM_CEXT_XSCALE)
===================================================================
Index: opcodes/arm-dis.c
--- opcodes/arm-dis.c	2005-03-08 16:25:03.000000000 -0800
+++ opcodes/arm-dis.c	2005-03-11 20:53:15.000000000 -0800
@@ -81,6 +81,8 @@
    %m			print register mask for ldm/stm instruction
    %C			print the PSR sub type.
    %F			print the COUNT field of a LFM/SFM instruction.
+   %E			print the LSB and WIDTH fields of a BFI or BFC instruction.
+   %V                   print the 16-bit immediate field of a MOVT or MOVW 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
@@ -118,6 +120,17 @@
   {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"},
 
+  /* 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"},
+  {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
+  {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
+  {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
+  {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
+  {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
+  {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
+  {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
+
   /* ARM V6Z instructions.  */
   {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
 
@@ -936,7 +949,13 @@
 	  && info->mach != bfd_mach_arm_iWMMXt)
 	insn = insn + IWMMXT_INSN_COUNT;
 
-      if ((given & insn->mask) == insn->value)
+      if ((given & insn->mask) == insn->value
+	  /* Special case: an instruction with all bits set in the condition field
+	     (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
+	     or by the catchall at the end of the table.  */
+	  && ((given & 0xF0000000) != 0xF0000000
+	      || (insn->mask & 0xF0000000) == 0xF0000000
+	      || (insn->mask == 0 && insn->value == 0)))
 	{
 	  char * c;
 
@@ -1620,6 +1639,32 @@
 			}
 			break;
 
+		      case 'E':
+			/* LSB and WIDTH fields of BFI or BFC.  The machine-
+			   language instruction encodes LSB and MSB.  */
+			{
+			  long msb = (given & 0x001f0000) >> 16;
+			  long lsb = (given & 0x00000f80) >> 7;
+
+			  long width = msb - lsb + 1;
+			  if (width > 0)
+			    func (stream, "#%lu, #%lu", lsb, width);
+			  else
+			    func (stream, "(invalid: %lu:%lu)", lsb, msb);
+			}
+			break;
+
+		      case 'V':
+			/* 16-bit unsigned immediate from a MOVT or MOVW
+			   instruction, encoded in bits 0:11 and 15:19.  */
+			{
+			  long hi = (given & 0x000f0000) >> 4;
+			  long lo = (given & 0x00000fff);
+			  long imm16 = hi | lo;
+			  func (stream, "#%lu\t; 0x%lx", imm16, imm16);
+			}
+			break;
+
 		      default:
 			abort ();
 		      }



More information about the Binutils mailing list