gdb/testsuite/
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
index 61bf91d118aeaed0a3ed0c7206b14df4875391ca..0d99c6c8ee03e46e14b45660565ccea3267006bd 100644 (file)
@@ -1,6 +1,6 @@
 /* Instruction printing code for the ARM
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2007, 2009  Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
    Modification by James G. Smith (jsmith@cygnus.co.uk)
 
@@ -69,7 +69,6 @@ struct opcode16
    %u                  print condition code (unconditional in ARM mode)
    %A                  print address for ldc/stc/ldf/stf instruction
    %B                  print vstm/vldm register list
-   %C                  print vstr/vldr address operand
    %I                   print cirrus signed shift immediate: bits 0..3|4..6
    %F                  print the COUNT field of a LFM/SFM instruction.
    %P                  print floating point precision in arithmetic insn
@@ -106,14 +105,15 @@ struct opcode16
                        (print "32" when 0)
    %r                  print register offset address for wldt/wstr instruction.  */
 
-enum
+enum opcode_sentinel_enum
 {
   SENTINEL_IWMMXT_START = 1,
   SENTINEL_IWMMXT_END,
   SENTINEL_GENERIC_START
 } opcode_sentinels;
 
-#define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
+#define UNDEFINED_INSTRUCTION      "undefined instruction %0-31x"
+#define UNPREDICTABLE_INSTRUCTION  "\t; <UNPREDICTABLE>"
 
 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
 
@@ -142,11 +142,11 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
-  {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
+  {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
   {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
   {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
-  {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
+  {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
   {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
   {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
@@ -247,8 +247,8 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
   {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
   {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
-  {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A\t; (stc%22'l%c %8-11d, cr%12-15d, %A)"},
-  {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A\t; (ldc%22'l%c %8-11d, cr%12-15d, %A)"},
+  {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
+  {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
 
   /* Register load/store.  */
   {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
@@ -257,8 +257,8 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
   {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
   {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
-  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
-  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
+  {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
   {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
   {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
   {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
@@ -289,8 +289,8 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
   {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
   /* Half-precision conversion instructions.  */
-  {FPU_NEON_FP16,   0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
-  {FPU_NEON_FP16,   0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_FP16, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
+  {FPU_VFP_EXT_FP16, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
 
   /* Floating point coprocessor (VFP) instructions.  */
   {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
@@ -330,14 +330,14 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
   {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
   {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
-  {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
+  {FPU_VFP_EXT_V3xD, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
   {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
   {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
   {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
-  {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
+  {FPU_VFP_EXT_V3xD, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
   {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
   {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
-  {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
+  {FPU_VFP_EXT_V3xD, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
   {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
   {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
   {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
@@ -447,6 +447,16 @@ static const struct opcode32 coprocessor_opcodes[] =
   {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
   {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
 
+  /* VFP Fused multiply add instructions.  */
+  {FPU_VFP_EXT_FMA, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_FMA, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_FMA, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_FMA, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_FMA, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_FMA, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_FMA, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_FMA, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
+
   /* Generic coprocessor instructions.  */
   { 0, SENTINEL_GENERIC_START, 0, "" },
   {ARM_EXT_V5E, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
@@ -517,8 +527,12 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
   
   /* Half-precision conversions.  */
-  {FPU_NEON_FP16,   0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
-  {FPU_NEON_FP16,   0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
+  {FPU_VFP_EXT_FP16, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
+  {FPU_VFP_EXT_FP16, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
+
+  /* NEON fused multiply add instructions.  */
+  {FPU_NEON_EXT_FMA, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
+  {FPU_NEON_EXT_FMA, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
 
   /* Two registers, miscellaneous.  */
   {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
@@ -762,6 +776,7 @@ static const struct opcode32 neon_opcodes[] =
 
    %a                  print address for ldr/str instruction
    %s                   print address for ldr/str halfword/signextend instruction
+   %S                   like %s but allow UNPREDICTABLE addressing
    %b                  print branch destination
    %c                  print condition code (always bits 28-31)
    %m                  print register mask for ldm/stm instruction
@@ -809,8 +824,8 @@ static const struct opcode32 arm_opcodes[] =
   {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, "strht%c\t%12-15r, %s"},
-  {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
+  {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %S"},
+  {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\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, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
@@ -1005,23 +1020,66 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
   {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
   {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
-  {ARM_EXT_V1, 0x000000b0, 0x0e1000f0, "strh%c\t%12-15r, %s"},
-  {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
-  {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
+  {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
+  {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
+  {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
+
+  {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15r, %16-19r, %o"},
+
   {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
   {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
-  {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
-  {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
+  {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15r, %16-19r, %o"},
+
   {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
   {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
   {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
@@ -1029,8 +1087,15 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
   {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
   {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
-  {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
-  {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
+
+  {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
+  {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15r, %16-19r, %o"},
+
+  {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
+  {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
+  {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15r, %o"},
+
   {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
   {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
   {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
@@ -1627,6 +1692,8 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
          else
            func (stream, ", #%d", amount);
        }
+      else if ((given & 0x80) == 0x80)
+       func (stream, ", <illegal shifter operand>");
       else if (print_shift)
        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
              arm_regnames[(given & 0xf00) >> 8]);
@@ -1635,6 +1702,16 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
     }
 }
 
+#define W_BIT 21
+#define I_BIT 22
+#define U_BIT 23
+#define P_BIT 24
+
+#define WRITEBACK_BIT_SET   (given & (1 << W_BIT))
+#define IMMEDIATE_BIT_SET   (given & (1 << I_BIT))
+#define NEGATIVE_BIT_SET   ((given & (1 << U_BIT)) == 0)
+#define PRE_BIT_SET         (given & (1 << P_BIT))
+
 /* Print one coprocessor instruction on INFO->STREAM.
    Return TRUE if the instuction matched, FALSE if this is not a
    recognised coprocessor instruction.  */
@@ -1730,20 +1807,27 @@ print_insn_coprocessor (bfd_vma pc,
 
                case 'A':
                  {
-                   int offset = given & 0xff;
+                   int rn = (given >> 16) & 0xf;
+                   int offset = given & 0xff;
 
                    func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
-                   value_in_comment = offset * 4;
-                   if ((given & 0x00800000) == 0)
-                     value_in_comment = - value_in_comment;
-                   
-                   if ((given & (1 << 24)) != 0)
+                   if (PRE_BIT_SET || WRITEBACK_BIT_SET)
+                     {
+                       /* Not unindexed.  The offset is scaled.  */
+                       offset = offset * 4;
+                       if (NEGATIVE_BIT_SET)
+                         offset = - offset;
+                       if (rn != 15)
+                         value_in_comment = offset;
+                     }
+
+                   if (PRE_BIT_SET)
                      {
                        if (offset)
                          func (stream, ", #%d]%s",
-                               value_in_comment,
-                               ((given & 0x00200000) != 0 ? "!" : ""));
+                               offset,
+                               WRITEBACK_BIT_SET ? "!" : "");
                        else
                          func (stream, "]");
                      }
@@ -1751,10 +1835,10 @@ print_insn_coprocessor (bfd_vma pc,
                      {
                        func (stream, "]");
 
-                       if (given & (1 << 21))
+                       if (WRITEBACK_BIT_SET)
                          {
                            if (offset)
-                             func (stream, ", #%d", value_in_comment);
+                             func (stream, ", #%d", offset);
                          }
                        else
                          {
@@ -1762,6 +1846,12 @@ print_insn_coprocessor (bfd_vma pc,
                            value_in_comment = offset;
                          }
                      }
+                   if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
+                     {
+                       func (stream, "\t; ");
+                       info->print_address_func (offset + pc
+                                                 + info->bytes_per_chunk * 2, info);
+                     }
                  }
                  break;
 
@@ -1779,34 +1869,6 @@ print_insn_coprocessor (bfd_vma pc,
                  }
                  break;
 
-               case 'C':
-                 {
-                   int rn = (given >> 16) & 0xf;
-                   int offset = (given & 0xff) * 4;
-                   int add = (given >> 23) & 1;
-
-                   func (stream, "[%s", arm_regnames[rn]);
-
-                   if (offset)
-                     {
-                       if (!add)
-                         offset = -offset;
-                       func (stream, ", #%d", offset);
-                       if (rn != 15)
-                         value_in_comment = offset;
-                     }
-                   func (stream, "]");
-                   if (rn == 15)
-                     {
-                       func (stream, "\t; ");
-                       /* FIXME: Unsure if info->bytes_per_chunk is the
-                          right thing to use here.  */
-                       info->print_address_func (offset + pc
-                                                 + info->bytes_per_chunk * 2, info);
-                     }
-                 }
-                 break;
-
                case 'c':
                  func (stream, "%s", arm_conditional[cond]);
                  break;
@@ -1955,7 +2017,7 @@ print_insn_coprocessor (bfd_vma pc,
                        break;
 
                      case 'x':
-                       func (stream, "0x%lx", value);
+                       func (stream, "0x%lx", (value & 0xffffffffUL));
                        break;
 
                      case '`':
@@ -2093,20 +2155,20 @@ print_insn_coprocessor (bfd_vma pc,
                      if (multiplier > 1)
                        {
                          value_in_comment = offset * multiplier;
-                         if ((given & 0x00800000) == 0)
+                         if (NEGATIVE_BIT_SET)
                            value_in_comment = - value_in_comment;
                        }
 
                      if (offset)
                        {
-                         if ((given & 0x01000000) != 0)
+                         if (PRE_BIT_SET)
                            func (stream, ", #%s%d]%s",
-                                 ((given & 0x00800000) == 0 ? "-" : ""),
+                                 NEGATIVE_BIT_SET ? "-" : "",
                                  offset * multiplier,
-                                 ((given & 0x00200000) != 0 ? "!" : ""));
+                                 WRITEBACK_BIT_SET ? "!" : "");
                          else
                            func (stream, "], #%s%d",
-                                 ((given & 0x00800000) == 0 ? "-" : ""),
+                                 NEGATIVE_BIT_SET ? "-" : "",
                                  offset * multiplier);
                        }
                      else
@@ -2117,8 +2179,8 @@ print_insn_coprocessor (bfd_vma pc,
                  case 'r':
                    {
                      int imm4 = (given >> 4) & 0xf;
-                     int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
-                     int ubit = (given >> 23) & 1;
+                     int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
+                     int ubit = ! NEGATIVE_BIT_SET;
                      const char *rm = arm_regnames [given & 0xf];
                      const char *rn = arm_regnames [(given >> 16) & 0xf];
 
@@ -2167,7 +2229,7 @@ print_insn_coprocessor (bfd_vma pc,
        }
 
       if (value_in_comment > 32 || value_in_comment < -16)
-       func (stream, "\t; 0x%lx", value_in_comment);
+       func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
 
       return TRUE;
     }
@@ -2193,9 +2255,9 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
 
       func (stream, "[pc");
 
-      if (given & 0x01000000)
+      if (PRE_BIT_SET)
        {
-         if ((given & 0x00800000) == 0)
+         if (NEGATIVE_BIT_SET)
            offset = - offset;
 
          /* Pre-indexed.  */
@@ -2207,15 +2269,14 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
             being used.  Probably a very dangerous thing
             for the programmer to do, but who are we to
             argue ?  */
-         if (given & 0x00200000)
+         if (WRITEBACK_BIT_SET)
            func (stream, "!");
        }
-      else
+      else  /* Post indexed.  */
        {
-         /* Post indexed.  */
          func (stream, "], #%d", offset);
 
-         /* ie ignore the offset.  */
+         /* Ie ignore the offset.  */
          offset = pc + 8;
        }
 
@@ -2227,26 +2288,25 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
     {
       func (stream, "[%s",
            arm_regnames[(given >> 16) & 0xf]);
-      if ((given & 0x01000000) != 0)
+
+      if (PRE_BIT_SET)
        {
          if ((given & 0x02000000) == 0)
            {
              offset = given & 0xfff;
              if (offset)
                func (stream, ", #%s%d",
-                     (((given & 0x00800000) == 0)
-                      ? "-" : ""), offset);
+                     NEGATIVE_BIT_SET ? "-" : "", offset);
            }
          else
            {
              func (stream, ", %s",
-                   (((given & 0x00800000) == 0)
-                    ? "-" : ""));
+                   NEGATIVE_BIT_SET ? "-" : "");
              arm_decode_shift (given, func, stream, TRUE);
            }
 
          func (stream, "]%s",
-               ((given & 0x00200000) != 0) ? "!" : "");
+               WRITEBACK_BIT_SET ? "!" : "");
        }
       else
        {
@@ -2255,16 +2315,14 @@ print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
              offset = given & 0xfff;
              if (offset)
                func (stream, "], #%s%d",
-                     (((given & 0x00800000) == 0)
-                      ? "-" : ""), offset);
+                     NEGATIVE_BIT_SET ? "-" : "", offset);
              else
                func (stream, "]");
            }
          else
            {
              func (stream, "], %s",
-                   (((given & 0x00800000) == 0)
-                    ? "-" : ""));
+                   NEGATIVE_BIT_SET ? "-" : "");
              arm_decode_shift (given, func, stream, TRUE);
            }
        }
@@ -2603,16 +2661,16 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                                 valbytes[3] = (value >> 24) & 0xff;
                                 
                                 floatformat_to_double 
-                                  (&floatformat_ieee_single_little, valbytes,
-                                  &fvalue);
+                                  (& floatformat_ieee_single_little, valbytes,
+                                  & fvalue);
                                                                 
                                 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
                                       value);
                               }
                             else
                               func (stream, "#%ld\t; 0x%.8lx",
-                               (long) ((value & 0x80000000)
-                                       ? value | ~0xffffffffl : value), value);
+                                   (long) (NEGATIVE_BIT_SET ? value | ~0xffffffffL : value),
+                                   value);
                             break;
 
                           case 64:
@@ -2775,6 +2833,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
            {
              if (*c == '%')
                {
+                 bfd_boolean allow_unpredictable = FALSE;
+
                  switch (*++c)
                    {
                    case '%':
@@ -2788,17 +2848,19 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                    case 'P':
                      /* Set P address bit and use normal address
                         printing routine.  */
-                     value_in_comment = print_arm_address (pc, info, given | (1 << 24));
+                     value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
                      break;
 
+                   case 'S':
+                     allow_unpredictable = TRUE;
                    case 's':
                       if ((given & 0x004f0000) == 0x004f0000)
                        {
                           /* PC relative with immediate offset.  */
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
 
-                         if ((given & 0x00800000) == 0)
-                           offset = -offset;
+                         if (NEGATIVE_BIT_SET)
+                           offset = - offset;
 
                          func (stream, "[pc, #%d]\t; ", offset);
                          info->print_address_func (offset + pc + 8, info);
@@ -2807,38 +2869,33 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        {
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
 
-                         if ((given & 0x00800000) == 0)
-                           offset = -offset;
+                         if (NEGATIVE_BIT_SET)
+                           offset = - offset;
 
                          func (stream, "[%s",
                                arm_regnames[(given >> 16) & 0xf]);
 
-                         if ((given & 0x01000000) != 0)
+                         if (PRE_BIT_SET)
                            {
                               /* Pre-indexed.  */
-                             if ((given & 0x00400000) == 0x00400000)
+                             if (IMMEDIATE_BIT_SET)
                                {
-                                  /* Immediate.  */
                                  if (offset)
                                    func (stream, ", #%d", offset);
                                  value_in_comment = offset;
                                }
-                             else
-                               {
-                                  /* Register.  */
-                                 func (stream, ", %s%s", offset < 0 ? "-" : "",
-                                        arm_regnames[given & 0xf]);
-                               }
+                             else /* Register.  */
+                               func (stream, ", %s%s",
+                                     NEGATIVE_BIT_SET ? "-" : "",
+                                     arm_regnames[given & 0xf]);
 
                              func (stream, "]%s",
-                                   ((given & 0x00200000) != 0) ? "!" : "");
+                                   WRITEBACK_BIT_SET ? "!" : "");
                            }
-                         else
+                         else /* Post-indexed.  */
                            {
-                              /* Post-indexed.  */
-                             if ((given & 0x00400000) == 0x00400000)
+                             if (IMMEDIATE_BIT_SET)
                                {
-                                  /* Immediate.  */
                                  if (offset)
                                    func (stream, "], #%d", offset);
                                  else
@@ -2846,12 +2903,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
 
                                  value_in_comment = offset;
                                }
-                             else
-                               {
-                                  /* Register.  */
-                                 func (stream, "], %s%s", offset < 0 ? "-" : "",
-                                        arm_regnames[given & 0xf]);
-                               }
+                             else /* Register.  */
+                               func (stream, "], %s%s",
+                                     NEGATIVE_BIT_SET ? "-" : "",
+                                     arm_regnames[given & 0xf]);
+
+                             if (WRITEBACK_BIT_SET && ! allow_unpredictable)
+                               func (stream, UNPREDICTABLE_INSTRUCTION);
                            }
                        }
                      break;
@@ -2921,17 +2979,17 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        int offset = given & 0xff;
 
                        value_in_comment = offset * 4;
-                       if ((given & 0x00800000) == 0)
+                       if (NEGATIVE_BIT_SET)
                          value_in_comment = - value_in_comment;
 
                        func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
 
-                       if ((given & (1 << 24)) != 0)
+                       if (PRE_BIT_SET)
                          {
                            if (offset)
                              func (stream, ", #%d]%s",
                                    value_in_comment,
-                                   ((given & 0x00200000) != 0 ? "!" : ""));
+                                   WRITEBACK_BIT_SET ? "!" : "");
                            else
                              func (stream, "]");
                          }
@@ -2939,7 +2997,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                          {
                            func (stream, "]");
 
-                           if (given & (1 << 21))
+                           if (WRITEBACK_BIT_SET)
                              {
                                if (offset)
                                  func (stream, ", #%d", value_in_comment);
@@ -2959,7 +3017,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                        bfd_vma address;
                        bfd_vma offset = 0;
 
-                       if (given & 0x00800000)
+                       if (! NEGATIVE_BIT_SET)
                          /* Is signed, hi bits should be ones.  */
                          offset = (-1) ^ 0x00ffffff;
 
@@ -3107,7 +3165,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
            }
 
          if (value_in_comment > 32 || value_in_comment < -16)
-           func (stream, "\t; 0x%lx", value_in_comment);
+           func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
          return;
        }
     }
@@ -3476,9 +3534,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                  switch (mod)
                    {
                    case 0: imm = imm8; break;
-                   case 1: imm = ((imm8<<16) | imm8); break;
-                   case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
-                   case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
+                   case 1: imm = ((imm8 << 16) | imm8); break;
+                   case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
+                   case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
                    default:
                      mod  = (bits & 0xf80) >> 7;
                      imm8 = (bits & 0x07f) | 0x80;
@@ -3554,7 +3612,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
              case 'a':
                {
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
-                 unsigned int U   = (given & 0x00800000) >> 23;
+                 unsigned int U   = ! NEGATIVE_BIT_SET;
                  unsigned int op  = (given & 0x00000f00) >> 8;
                  unsigned int i12 = (given & 0x00000fff);
                  unsigned int i8  = (given & 0x000000ff);
@@ -3636,14 +3694,14 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 
              case 'A':
                {
-                 unsigned int P   = (given & 0x01000000) >> 24;
-                 unsigned int U   = (given & 0x00800000) >> 23;
-                 unsigned int W   = (given & 0x00400000) >> 21;
+                 unsigned int U   = ! NEGATIVE_BIT_SET;
+                 unsigned int W   = WRITEBACK_BIT_SET;
                  unsigned int Rn  = (given & 0x000f0000) >> 16;
                  unsigned int off = (given & 0x000000ff);
 
                  func (stream, "[%s", arm_regnames[Rn]);
-                 if (P)
+
+                 if (PRE_BIT_SET)
                    {
                      if (off || !U)
                        {
@@ -3778,7 +3836,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 
                  shift |= (given & 0x000000c0u) >> 6;
                  shift |= (given & 0x00007000u) >> 10;
-                 if (given & 0x00200000u)
+                 if (WRITEBACK_BIT_SET)
                    func (stream, ", asr #%u", shift);
                  else if (shift)
                    func (stream, ", lsl #%u", shift);
@@ -4214,8 +4272,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
 
   /* First check the full symtab for a mapping symbol, even if there
      are no usable non-mapping symbols for this address.  */
-  if (info->symtab != NULL
-      && * info->symtab
+  if (info->symtab_size != 0
       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
     {
       bfd_vma addr;
This page took 0.034825 seconds and 4 git commands to generate.