This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] assembler/disassembler support for ARM "udf" mnemonic
- From: Roland McGrath <mcgrathr at google dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Fri, 30 Aug 2013 15:16:20 -0700
- Subject: [PATCH] assembler/disassembler support for ARM "udf" mnemonic
- Authentication-results: sourceware.org; auth=none
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;