This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] assembler/disassembler support for ARM "udf" mnemonic


This makes the ARM assembler and disassembler grok the "udf" mnemonic for
the "permanently undefined" opcode ranges.  AIUI these opcode ranges have
been specified with "permanently undefined" meaning from the beginning of
ARM (and Thumb, and Thumb-2).  But only quite recent editions of the ARM
instruction set manual describe an assembly syntax for them.

I think I've covered all the cases correctly, but this should certainly get
some close scrutiny by an actual ARM expert.

No 'make check' failures for arm-linux-gnueabi or arm-nacl targets.

OK for trunk?


Thanks,
Roland



gas/
2013-08-30  Roland McGrath  <mcgrathr@google.com>

	* config/tc-arm.c (T16_32_TAB): Add _udf.
	(do_t_udf): New function.
	(insns): Add "udf".

gas/testsuite/
2013-08-30  Roland McGrath  <mcgrathr@google.com>

	* gas/arm/udf-bad.s: New file.
	* gas/arm/udf-bad.d: New file.
	* gas/arm/udf-bad.l: New file.
	* gas/arm/udf.s: New file.
	* gas/arm/udf.d: New file.
	* gas/arm/udf.l: New file.

opcodes/
2013-08-30  Roland McGrath  <mcgrathr@google.com>

	* arm-dis.c (arm_opcodes): Add udf.
	(thumb_opcodes): Use "udf" mnemonic rather than UNDEFINED_INSTRUCTION.
	(thumb32_opcodes): Add udf.w.
	(print_insn_thumb32): Handle %H as the thumb32_opcodes comment says.

--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -9563,7 +9563,8 @@ encode_thumb32_addr_mode (int i, bfd_boolean
is_t, bfd_boolean is_d)
   X(_wfe,   bf20, f3af8002),			\
   X(_wfi,   bf30, f3af8003),			\
   X(_sev,   bf40, f3af8004),                    \
-  X(_sevl,  bf50, f3af8005)
+  X(_sevl,  bf50, f3af8005),			\
+  X(_udf,   de00, f7f0a000)

 /* To catch errors in encoding functions, the codes are all offset by
    0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
@@ -12219,6 +12220,30 @@ do_t_tb (void)
 }

 static void
+do_t_udf (void)
+{
+  if (!inst.operands[0].present)
+    inst.operands[0].imm = 0;
+
+  if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
+    {
+      constraint (inst.size_req == 2,
+                  _("immediate value out of range"));
+      inst.instruction = THUMB_OP32 (inst.instruction);
+      inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
+      inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
+    }
+  else
+    {
+      inst.instruction = THUMB_OP16 (inst.instruction);
+      inst.instruction |= inst.operands[0].imm;
+    }
+
+  set_it_insn_type (NEUTRAL_IT_INSN);
+}
+
+
+static void
 do_t_usat (void)
 {
   do_t_ssat_usat (0);
@@ -18029,6 +18054,7 @@ static const struct asm_opcode insns[] =
  tCE("adr",	28f0000, _adr,	   2, (RR, EXP),     adr,  t_adr),
   C3(adrl,	28f0000,           2, (RR, EXP),     adrl),
  tCE("nop",	1a00000, _nop,	   1, (oI255c),	     nop,  t_nop),
+ tCE("udf",	7f000f0, _udf,     1, (oIffffb),     bkpt, t_udf),

   /* Thumb-compatibility pseudo ops.  */
  tCE("lsl",	1a00000, _lsl,	   3, (RR, oRR, SH), shift, t_shift),
--- /dev/null
+++ b/gas/testsuite/gas/arm/udf-bad.d
@@ -0,0 +1,2 @@
+#name: Invalid UDF operands
+#error-output: udf-bad.l
--- /dev/null
+++ b/gas/testsuite/gas/arm/udf-bad.l
@@ -0,0 +1,5 @@
+[^:]*: Assembler messages:
+^[^:]*:4: Error: immediate value out of range -- `udf #0x10000'
+^[^:]*:7: Error: immediate value out of range -- `udf #0x10000'
+^[^:]*:8: Error: immediate value out of range -- `udf.w #0x10000'
+^[^:]*:9: Error: immediate value out of range -- `udf.n #0x100'
--- /dev/null
+++ b/gas/testsuite/gas/arm/udf-bad.s
@@ -0,0 +1,9 @@
+	.syntax unified
+
+arm:	.arm
+	udf	#0x10000
+
+thumb:	.thumb
+	udf	#0x10000
+	udf.w	#0x10000
+	udf.n	#0x100
--- /dev/null
+++ b/gas/testsuite/gas/arm/udf.d
@@ -0,0 +1,30 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: UDF
+#error-output: udf.l
+
+.*: +file format .*arm.*
+
+Disassembly of section \.text:
+
+0+0 <arm>:
+\s*0:\s+e7f000f0\s+udf	#0
+\s*4:\s+e7fabcfd\s+udf	#43981	; 0xabcd
+
+0+0 <thumb>:
+\s*8:\s+deab\s+udf	#171	; 0xab
+\s*a:\s+decd\s+udf	#205	; 0xcd
+\s*c:\s+de00\s+udf	#0
+\s*e:\s+46c0\s+nop.*
+\s*10:\s+f7f0 a000\s+udf\.w	#0
+\s*14:\s+f7f1 a234\s+udf\.w	#4660	; 0x1234
+\s*18:\s+f7fc acdd\s+udf\.w	#52445	; 0xccdd
+\s*1c:\s+bf08\s+it	eq
+\s*1e:\s+de12\s+udfeq	#18
+\s*20:\s+de23\s+udf	#35	; 0x23
+\s*22:\s+de34\s+udf	#52	; 0x34
+\s*24:\s+de56\s+udf	#86	; 0x56
+\s*26:\s+bf18\s+it	ne
+\s*28:\s+f7f1 a234\s+udfne\.w	#4660	; 0x1234
+\s*2c:\s+f7f2 a345\s+udf\.w	#9029	; 0x2345
+\s*30:\s+f7f3 a456\s+udf\.w	#13398	; 0x3456
+\s*34:\s+f7f5 a678\s+udf\.w	#22136	; 0x5678
--- /dev/null
+++ b/gas/testsuite/gas/arm/udf.l
@@ -0,0 +1,3 @@
+^[^:]*: Assembler messages:
+^[^:]*:16: Warning: IT blocks containing 16-bit Thumb instructions of
the following class are deprecated in ARMv8: Short branches,
Undefined, SVC, LDM/STM
+^[^:]*:21: Warning: IT blocks containing 32-bit Thumb instructions
are deprecated in ARMv8
--- /dev/null
+++ b/gas/testsuite/gas/arm/udf.s
@@ -0,0 +1,24 @@
+	.syntax unified
+
+arm:	.arm
+	udf
+	udf	#0xabcd
+
+thumb:	.thumb
+	udf	#0xab
+	udf.n	#0xcd
+	udf
+	nop
+	udf.w
+	udf	#0x1234
+	udf.w	#0xccdd
+	it	eq
+	udf	#0x12
+	udf	#0x23
+	udf	#0x34
+	udf	#0x56
+	it	ne
+	udf	#0x1234
+	udf	#0x2345
+	udf	#0x3456
+	udf	#0x5678
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -879,6 +879,8 @@ static const struct opcode32 arm_opcodes[] =
 {
   /* ARM instructions.  */
   {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
+  {ARM_EXT_V1, 0xe7f000f0, 0xfff000f0, "udf\t#%e"},
+
   {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
   {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
   {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R,
%8-11R, %12-15R"},
@@ -1414,6 +1416,7 @@ static const struct opcode16 thumb_opcodes[] =
   /* format 17 */
   {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
   /* format 16 */
+  {ARM_EXT_V4T, 0xDE00, 0xFF00, "udf%c\t#%0-7d"},
   {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
   {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
   /* format 18 */
@@ -1534,6 +1537,7 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
   {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
   {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
+  {ARM_EXT_V6T2, 0xf7f0a000, 0xfff0f000, "udf%c.w\t%H"},

   {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
   {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
@@ -4057,6 +4061,17 @@ print_insn_thumb32 (bfd_vma pc, struct
disassemble_info *info, long given)
 		}
 		break;

+	      case 'H':
+		{
+		  unsigned int imm = 0;
+
+		  imm |= (given & 0x000f0000u) >> 4;
+		  imm |= (given & 0x00000fffu) >> 0;
+		  func (stream, "#%u", imm);
+		  value_in_comment = imm;
+		}
+		break;
+
 	      case 'V':
 		{
 		  unsigned int imm = 0;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]