X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Farm-dis.c;h=59a5978984cc1c1f4aba79993917befa5d141a28;hb=cc4a945a2687184c7cd4a0572e02965829517408;hp=3e1315ff4b3ab28e6f79741609a5c904fd8e3d60;hpb=ddfded2f7bba485d6c967b502337a72310f24913;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 3e1315ff4b..59a5978984 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -1,5 +1,5 @@ /* Instruction printing code for the ARM - Copyright (C) 1994-2015 Free Software Foundation, Inc. + Copyright (C) 1994-2017 Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Modification by James G. Smith (jsmith@cygnus.co.uk) @@ -22,10 +22,11 @@ #include "sysdep.h" -#include "dis-asm.h" +#include "disassemble.h" #include "opcode/arm.h" #include "opintl.h" #include "safe-ctype.h" +#include "libiberty.h" #include "floatformat.h" /* FIXME: This shouldn't be done here. */ @@ -34,16 +35,13 @@ #include "elf-bfd.h" #include "elf/internal.h" #include "elf/arm.h" +#include "mach-o.h" /* FIXME: Belongs in global header. */ #ifndef strneq #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) #endif -#ifndef NUM_ELEM -#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) -#endif - /* Cached mapping symbol state. */ enum map_type { @@ -115,6 +113,8 @@ struct opcode16 %G print as an iWMMXt general purpose or control register %D print as a NEON D register %Q print as a NEON Q register + %V print as a NEON D or Q register + %E print a quarter-float immediate value %y print a single precision VFP reg. Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair @@ -124,7 +124,7 @@ struct opcode16 %'c print specified char iff bitfield is all ones %`c print specified char iff bitfield is all zeroes %?ab... select from array of values in big endian order - + %L print as an iWMMXt N/M width field. %Z print the Immediate of a WSHUFH instruction. %l like 'A' except use byte offsets for 'B' & 'H' @@ -406,6 +406,12 @@ static const struct opcode32 coprocessor_opcodes[] = {ARM_FEATURE_COPROC (FPU_FPA_EXT_V2), 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"}, + /* ARMv8-M Mainline Security Extensions instructions. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN), + 0xec300a00, 0xfff0ffff, "vlldm\t%16-19r"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN), + 0xec200a00, 0xfff0ffff, "vlstm\t%16-19r"}, + /* Register load/store. */ {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1), 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"}, @@ -497,6 +503,8 @@ static const struct opcode32 coprocessor_opcodes[] = 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD), 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"}, + {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), + 0x0ee50a10, 0x0fff0fff, "vmsr%c\tmvfr2, %12-15r"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD), 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD), @@ -509,6 +517,8 @@ static const struct opcode32 coprocessor_opcodes[] = 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD), 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"}, + {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), + 0x0ef50a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr2"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD), 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD), @@ -578,9 +588,9 @@ static const struct opcode32 coprocessor_opcodes[] = {ARM_FEATURE_COPROC (FPU_VFP_EXT_V1), 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V3xD), - 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"}, + 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19E"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V3), - 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"}, + 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19E"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V2), 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_V2), @@ -818,17 +828,17 @@ static const struct opcode32 coprocessor_opcodes[] = /* FP v5. */ {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfe000a00, 0xff800f00, "vsel%20-21c%u.f32\t%y1, %y2, %y0"}, + 0xfe000a00, 0xff800f50, "vsel%20-21c%u.f32\t%y1, %y2, %y0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfe000b00, 0xff800f00, "vsel%20-21c%u.f64\t%z1, %z2, %z0"}, + 0xfe000b00, 0xff800f50, "vsel%20-21c%u.f64\t%z1, %z2, %z0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfe800a00, 0xffb00f40, "vmaxnm%u.f32\t%y1, %y2, %y0"}, + 0xfe800a00, 0xffb00f50, "vmaxnm%u.f32\t%y1, %y2, %y0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfe800b00, 0xffb00f40, "vmaxnm%u.f64\t%z1, %z2, %z0"}, + 0xfe800b00, 0xffb00f50, "vmaxnm%u.f64\t%z1, %z2, %z0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfe800a40, 0xffb00f40, "vminnm%u.f32\t%y1, %y2, %y0"}, + 0xfe800a40, 0xffb00f50, "vminnm%u.f32\t%y1, %y2, %y0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfe800b40, 0xffb00f40, "vminnm%u.f64\t%z1, %z2, %z0"}, + 0xfe800b40, 0xffb00f50, "vminnm%u.f64\t%z1, %z2, %z0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), 0xfebc0a40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f32\t%y1, %y0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), @@ -838,9 +848,9 @@ static const struct opcode32 coprocessor_opcodes[] = {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), 0x0eb60b40, 0x0fbe0f50, "vrint%7,16??xzr%c.f64\t%z1, %z0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfeb80a40, 0xffbc0f50, "vrint%16-17?mpna%u.f32\t%y1, %y0"}, + 0xfeb80a40, 0xffbc0fd0, "vrint%16-17?mpna%u.f32\t%y1, %y0"}, {ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), - 0xfeb80b40, 0xffbc0f50, "vrint%16-17?mpna%u.f64\t%z1, %z0"}, + 0xfeb80b40, 0xffbc0fd0, "vrint%16-17?mpna%u.f64\t%z1, %z0"}, /* Generic coprocessor instructions. */ {ARM_FEATURE_CORE_LOW (0), SENTINEL_GENERIC_START, 0, "" }, @@ -874,6 +884,34 @@ static const struct opcode32 coprocessor_opcodes[] = 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"}, + /* ARMv8.3 AdvSIMD instructions in the space of coprocessor 8. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfc800800, 0xfeb00f10, "vcadd%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%24?29%24'70"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfc900800, 0xfeb00f10, "vcadd%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%24?29%24'70"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfc200800, 0xff300f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%23'90"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfd200800, 0xff300f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%23?21%23?780"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfc300800, 0xff300f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%23'90"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfd300800, 0xff300f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5V, #%23?21%23?780"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfe000800, 0xffa00f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3D[%5?10], #%20'90"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfe200800, 0xffa00f10, "vcmla%c.f16\t%12-15,22V, %16-19,7V, %0-3D[%5?10], #%20?21%20?780"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfe800800, 0xffa00f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5D[0], #%20'90"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0xfea00800, 0xffa00f10, "vcmla%c.f32\t%12-15,22V, %16-19,7V, %0-3,5D[0], #%20?21%20?780"}, + + /* Dot Product instructions in the space of coprocessor 13. */ + {ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD), + 0xfc200d00, 0xffb00f00, "v%4?usdot.%4?us8\t%12-15,22V, %16-19,7V, %0-3,5V"}, + {ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD), + 0xfe000d00, 0xff000f00, "v%4?usdot.%4?us8\t%12-15,22V, %16-19,7V, %0-3D[%5?10]"}, + /* V5 coprocessor instructions. */ {ARM_FEATURE_CORE_LOW (ARM_EXT_V5), 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"}, @@ -889,6 +927,84 @@ static const struct opcode32 coprocessor_opcodes[] = 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + /* ARMv8.2 half-precision Floating point coprocessor 9 (VFP) instructions. + cp_num: bit <11:8> == 0b1001. + cond: bit <31:28> == 0b1110, otherwise, it's UNPREDICTABLE. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eb009c0, 0x0fbf0fd0, "vabs%c.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e300900, 0x0fb00f50, "vadd%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eb40940, 0x0fbf0f50, "vcmp%7'e%c.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eb50940, 0x0fbf0f70, "vcmp%7'e%c.f16\t%y1, #0.0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eba09c0, 0x0fbe0fd0, "vcvt%c.f16.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0ebe09c0, 0x0fbe0fd0, "vcvt%c.%16?us%7?31%7?26.f16\t%y1, %y1, #%5,0-3k"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0ebc0940, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eb80940, 0x0fbf0f50, "vcvt%c.f16.%7?su32\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xfebc0940, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e800900, 0x0fb00f50, "vdiv%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0ea00900, 0x0fb00f50, "vfma%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0ea00940, 0x0fb00f50, "vfms%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e900940, 0x0fb00f50, "vfnma%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e900900, 0x0fb00f50, "vfnms%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xfeb00ac0, 0xffbf0fd0, "vins.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xfeb00a40, 0xffbf0fd0, "vmovx%c.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0d100900, 0x0f300f00, "vldr%c.16\t%y1, %A"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0d000900, 0x0f300f00, "vstr%c.16\t%y1, %A"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xfe800900, 0xffb00f50, "vmaxnm%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xfe800940, 0xffb00f50, "vminnm%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e000900, 0x0fb00f50, "vmla%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e000940, 0x0fb00f50, "vmls%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e100910, 0x0ff00f7f, "vmov%c.f16\t%12-15r, %y2"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e000910, 0x0ff00f7f, "vmov%c.f16\t%y2, %12-15r"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xeb00900, 0x0fb00ff0, "vmov%c.f16\t%y1, #%0-3,16-19E"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e200900, 0x0fb00f50, "vmul%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eb10940, 0x0fbf0fd0, "vneg%c.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e100940, 0x0fb00f50, "vnmla%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e100900, 0x0fb00f50, "vnmls%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e200940, 0x0fb00f50, "vnmul%c.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eb60940, 0x0fbe0f50, "vrint%7,16??xzr%c.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xfeb80940, 0xffbc0fd0, "vrint%16-17?mpna%u.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xfe000900, 0xff800f50, "vsel%20-21c%u.f16\t%y1, %y2, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0eb109c0, 0x0fbf0fd0, "vsqrt%c.f16\t%y1, %y0"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0x0e300940, 0x0fb00f50, "vsub%c.f16\t%y1, %y2, %y0"}, + + /* ARMv8.3 javascript conversion instruction. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), + 0x0eb90bc0, 0x0fbf0fd0, "vjcvt%c.s32.f64\t%y1, %z0"}, + {ARM_FEATURE_CORE_LOW (0), 0, 0, 0} }; @@ -919,7 +1035,7 @@ static const struct opcode32 coprocessor_opcodes[] = %Sn print byte scaled width limited by n %Tn print short scaled width limited by n %Un print long scaled width limited by n - + %'c print specified char iff bitfield is all ones %`c print specified char iff bitfield is all zeroes %?ab... select from array of values in big endian order. */ @@ -956,15 +1072,23 @@ static const struct opcode32 neon_opcodes[] = /* NEON fused multiply add instructions. */ {ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA), - 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2000c10, 0xffb00f10, "vfma%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2100c10, 0xffb00f10, "vfma%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA), - 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2200c10, 0xffb00f10, "vfms%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2300c10, 0xffb00f10, "vfms%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, /* Two registers, miscellaneous. */ {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8), 0xf3ba0400, 0xffbf0c10, "vrint%7-9?p?m?zaxn%u.f32\t%12-15,22R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3b60400, 0xffbf0c10, "vrint%7-9?p?m?zaxn%u.f16\t%12-15,22R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8), 0xf3bb0000, 0xffbf0c10, "vcvt%8-9?mpna%u.%7?us32.f32\t%12-15,22R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3b70000, 0xffbf0c10, "vcvt%8-9?mpna%u.%7?us16.f16\t%12-15,22R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8), 0xf3b00300, 0xffbf0fd0, "aese%u.8\t%12-15,22Q, %0-3,5Q"}, {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8), @@ -1004,8 +1128,12 @@ static const struct opcode32 neon_opcodes[] = "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3b70400, 0xffbf0e90, "vrecpe%c.%8?fu16\t%12-15,22R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3b70480, 0xffbf0e90, "vrsqrte%c.%8?fu16\t%12-15,22R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), @@ -1045,8 +1173,11 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3b30600, 0xffb30e10, + 0xf3bb0600, 0xffbf0e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3b70600, 0xffbf0e10, + "vcvt%c.%7-8?usff16.%7-8?ffus16\t%12-15,22R, %0-3,5R"}, /* Three registers of the same length. */ {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8), @@ -1064,9 +1195,13 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8), 0xf3200c40, 0xffb00f50, "sha256su1%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8), - 0xf3000f10, 0xffa00f10, "vmaxnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3000f10, 0xffb00f10, "vmaxnm%u.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3100f10, 0xffb00f10, "vmaxnm%u.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8), - 0xf3200f10, 0xffa00f10, "vminnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3200f10, 0xffb00f10, "vminnm%u.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3300f10, 0xffb00f10, "vminnm%u.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), @@ -1084,41 +1219,77 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2000d00, 0xffb00f10, "vadd%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2100d00, 0xffb00f10, "vadd%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2000d10, 0xffb00f10, "vmla%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2100d10, 0xffb00f10, "vmla%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2000e00, 0xffb00f10, "vceq%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2100e00, 0xffb00f10, "vceq%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2000f00, 0xffb00f10, "vmax%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2100f00, 0xffb00f10, "vmax%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2000f10, 0xffb00f10, "vrecps%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2100f10, 0xffb00f10, "vrecps%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2200d00, 0xffb00f10, "vsub%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2300d00, 0xffb00f10, "vsub%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2200d10, 0xffb00f10, "vmls%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2300d10, 0xffb00f10, "vmls%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2200f00, 0xffb00f10, "vmin%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2300f00, 0xffb00f10, "vmin%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf2200f10, 0xffb00f10, "vrsqrts%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2300f10, 0xffb00f10, "vrsqrts%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3000d00, 0xffb00f10, "vpadd%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3100d00, 0xffb00f10, "vpadd%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3000d10, 0xffb00f10, "vmul%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3100d10, 0xffb00f10, "vmul%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3000e00, 0xffb00f10, "vcge%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3100e00, 0xffb00f10, "vcge%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3000e10, 0xffb00f10, "vacge%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3100e10, 0xffb00f10, "vacge%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3000f00, 0xffb00f10, "vpmax%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3100f00, 0xffb00f10, "vpmax%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3200d00, 0xffb00f10, "vabd%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3300d00, 0xffb00f10, "vabd%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3200e00, 0xffb00f10, "vcgt%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3300e00, 0xffb00f10, "vcgt%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3200e10, 0xffb00f10, "vacgt%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3300e10, 0xffb00f10, "vacgt%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, + 0xf3200f00, 0xffb00f10, "vpmin%c.f32\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf3300f00, 0xffb00f10, "vpmin%c.f16\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), @@ -1194,6 +1365,12 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA), + 0xf3000b10, 0xff800f10, + "vqrdmlah%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"}, + {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA), + 0xf3000c10, 0xff800f10, + "vqrdmlsh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"}, /* One register and an immediate value. */ {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), @@ -1344,6 +1521,9 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), + 0xf2a00c10, 0xfea00e90, + "vcvt%c.%24,8?usff16.%24,8?ffus16\t%12-15,22R, %0-3,5R, #%16-20e"}, /* Three registers of different lengths. */ {ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8), @@ -1403,19 +1583,25 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, + 0xf2800140, 0xff900f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, + {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST), + 0xf2900140, 0xffb00f50, "vmla%c.f16\t%12-15,22D, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + 0xf2800540, 0xff900f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST), + 0xf2900540, 0xffb00f50, "vmls%c.f16\t%12-15,22D, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, + 0xf2800940, 0xff900f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, + {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST), + 0xf2900940, 0xffb00f50, "vmul%c.f16\t%12-15,22D, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), @@ -1425,15 +1611,21 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + 0xf3800140, 0xff900f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST), + 0xf3900140, 0xffb00f50, "vmla%c.f16\t%12-15,22Q, %16-19,7Q, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + 0xf3800540, 0xff900f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST), + 0xf3900540, 0xffb00f50, "vmls%c.f16\t%12-15,22Q, %16-19,7Q, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), - 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + 0xf3800940, 0xff900f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, + {ARM_FEATURE_COPROC (ARM_EXT2_FP16_INST), + 0xf3900940, 0xffb00f50, "vmul%c.f16\t%12-15,22Q, %16-19,7Q, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), @@ -1447,6 +1639,19 @@ static const struct opcode32 neon_opcodes[] = {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, + {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA), + 0xf2800e40, 0xff800f50, + "vqrdmlah%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA), + 0xf2800f40, 0xff800f50, + "vqrdmlsh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"}, + {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA), + 0xf3800e40, 0xff800f50, + "vqrdmlah%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, + {ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA), + 0xf3800f40, 0xff800f50, + "vqrdmlsh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D" + }, /* Element and structure load/store. */ {ARM_FEATURE_COPROC (FPU_NEON_EXT_V1), @@ -1519,10 +1724,10 @@ static const struct opcode32 neon_opcodes[] = %{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE %{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE %d print the bitfield in decimal - %W print the bitfield plus one in decimal + %W print the bitfield plus one in decimal %x print the bitfield in hex %X print the bitfield as 1 hex digit without leading "0x" - + %'c print specified char iff bitfield is all ones %`c print specified char iff bitfield is all zeroes %?ab... select from array of values in big endian order @@ -1555,39 +1760,43 @@ static const struct opcode32 arm_opcodes[] = 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"}, + /* V8.2 RAS extension instructions. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS), + 0xe320f010, 0xffffffff, "esb"}, + /* V8 instructions. */ {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), 0x0320f005, 0x0fffffff, "sevl"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), 0xe1000070, 0xfff000f0, "hlt\t0x%16-19X%12-15X%8-11X%0-3X"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS), 0x01800e90, 0x0ff00ff0, "stlex%c\t%12-15r, %0-3r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01900e9f, 0x0ff00fff, "ldaex%c\t%12-15r, [%16-19R]"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), 0x01a00e90, 0x0ff00ff0, "stlexd%c\t%12-15r, %0-3r, %0-3T, [%16-19R]"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), 0x01b00e9f, 0x0ff00fff, "ldaexd%c\t%12-15r, %12-15T, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01c00e90, 0x0ff00ff0, "stlexb%c\t%12-15r, %0-3r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01d00e9f, 0x0ff00fff, "ldaexb%c\t%12-15r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01e00e90, 0x0ff00ff0, "stlexh%c\t%12-15r, %0-3r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01f00e9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x0180fc90, 0x0ff0fff0, "stl%c\t%0-3r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01900c9f, 0x0ff00fff, "lda%c\t%12-15r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01c0fc90, 0x0ff0fff0, "stlb%c\t%0-3r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01d00c9f, 0x0ff00fff, "ldab%c\t%12-15r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), 0x01e0fc90, 0x0ff0fff0, "stlh%c\t%0-3r, [%16-19R]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), - 0x01f00c9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"}, + {ARM_FEATURE_CORE_LOW (ARM_EXT2_ATOMICS), + 0x01f00c9f, 0x0ff00fff, "ldah%c\t%12-15r, [%16-19R]"}, /* CRC32 instructions. */ {ARM_FEATURE_COPROC (CRC_EXT_ARMV8), 0xe1000040, 0xfff00ff0, "crc32b\t%12-15R, %16-19R, %0-3R"}, @@ -1627,6 +1836,8 @@ static const struct opcode32 arm_opcodes[] = {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf57ff050, 0xfffffff0, "dmb\t%U"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf57ff040, 0xfffffff0, "dsb\t%U"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf57ff060, 0xfffffff0, "isb\t%U"}, + {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), + 0x0320f000, 0x0fffffff, "nop%c\t{%0-7d}"}, /* ARM V6T2 instructions. */ {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), @@ -1643,9 +1854,9 @@ static const struct opcode32 arm_opcodes[] = {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"}, @@ -2104,11 +2315,11 @@ static const struct opcode32 arm_opcodes[] = 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V1), - 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"}, + 0x03300000, 0x0ff00000, "teq%p%c\t%16-19r, %o"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V1), - 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"}, + 0x01300000, 0x0ff00010, "teq%p%c\t%16-19r, %o"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V1), - 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"}, + 0x01300010, 0x0ff00010, "teq%p%c\t%16-19R, %o"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V1), 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"}, @@ -2257,6 +2468,8 @@ static const struct opcode32 arm_opcodes[] = 0x0f000000, 0x0f000000, "svc%c\t%0-23x"}, /* The rest. */ + {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), + 0x03200000, 0x0fff00ff, "nop%c\t{%0-7d}" UNPREDICTABLE_INSTRUCTION}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V1), 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION}, {ARM_FEATURE_CORE_LOW (0), @@ -2294,6 +2507,10 @@ static const struct opcode16 thumb_opcodes[] = { /* Thumb instructions. */ + /* ARMv8-M Security Extensions instructions. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), 0x4784, 0xff87, "blxns\t%3-6r"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), 0x4704, 0xff07, "bxns\t%3-6r"}, + /* ARM V8 instructions. */ {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), 0xbf50, 0xffff, "sevl%c"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), 0xba80, 0xffc0, "hlt\t%0-5x"}, @@ -2308,8 +2525,10 @@ static const struct opcode16 thumb_opcodes[] = {ARM_FEATURE_CORE_LOW (ARM_EXT_V6K), 0xbf00, 0xff0f, "nop%c\t{%4-7d}"}, /* ARM V6T2 instructions. */ - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), + 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), + 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xbf00, 0xff00, "it%I%X"}, /* ARM V6. */ @@ -2480,7 +2699,6 @@ static const struct opcode16 thumb_opcodes[] = %W print bitfield*4 in decimal %r print bitfield as an ARM register %R as %<>r but r15 is UNPREDICTABLE - %S as %<>R but r13 is UNPREDICTABLE %c print bitfield as a condition code %'c print specified char iff bitfield is all ones @@ -2497,6 +2715,21 @@ static const struct opcode16 thumb_opcodes[] = makes heavy use of special-case bit patterns. */ static const struct opcode32 thumb32_opcodes[] = { + /* ARMv8-M and ARMv8-M Security Extensions instructions. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), 0xe97fe97f, 0xffffffff, "sg"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), + 0xe840f000, 0xfff0f0ff, "tt\t%8-11r, %16-19r"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), + 0xe840f040, 0xfff0f0ff, "ttt\t%8-11r, %16-19r"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), + 0xe840f080, 0xfff0f0ff, "tta\t%8-11r, %16-19r"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), + 0xe840f0c0, 0xfff0f0ff, "ttat\t%8-11r, %16-19r"}, + + /* ARM V8.2 RAS extension instructions. */ + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS), + 0xf3af8010, 0xffffffff, "esb"}, + /* V8 instructions. */ {ARM_FEATURE_CORE_LOW (ARM_EXT_V8), 0xf3af8005, 0xffffffff, "sevl%c.w"}, @@ -2533,17 +2766,17 @@ static const struct opcode32 thumb32_opcodes[] = /* CRC32 instructions. */ {ARM_FEATURE_COPROC (CRC_EXT_ARMV8), - 0xfac0f080, 0xfff0f0f0, "crc32b\t%8-11S, %16-19S, %0-3S"}, + 0xfac0f080, 0xfff0f0f0, "crc32b\t%8-11R, %16-19R, %0-3R"}, {ARM_FEATURE_COPROC (CRC_EXT_ARMV8), - 0xfac0f090, 0xfff0f0f0, "crc32h\t%9-11S, %16-19S, %0-3S"}, + 0xfac0f090, 0xfff0f0f0, "crc32h\t%9-11R, %16-19R, %0-3R"}, {ARM_FEATURE_COPROC (CRC_EXT_ARMV8), - 0xfac0f0a0, 0xfff0f0f0, "crc32w\t%8-11S, %16-19S, %0-3S"}, + 0xfac0f0a0, 0xfff0f0f0, "crc32w\t%8-11R, %16-19R, %0-3R"}, {ARM_FEATURE_COPROC (CRC_EXT_ARMV8), - 0xfad0f080, 0xfff0f0f0, "crc32cb\t%8-11S, %16-19S, %0-3S"}, + 0xfad0f080, 0xfff0f0f0, "crc32cb\t%8-11R, %16-19R, %0-3R"}, {ARM_FEATURE_COPROC (CRC_EXT_ARMV8), - 0xfad0f090, 0xfff0f0f0, "crc32ch\t%8-11S, %16-19S, %0-3S"}, + 0xfad0f090, 0xfff0f0f0, "crc32ch\t%8-11R, %16-19R, %0-3R"}, {ARM_FEATURE_COPROC (CRC_EXT_ARMV8), - 0xfad0f0a0, 0xfff0f0f0, "crc32cw\t%8-11S, %16-19S, %0-3S"}, + 0xfad0f0a0, 0xfff0f0f0, "crc32cw\t%8-11R, %16-19R, %0-3R"}, /* V7 instructions. */ {ARM_FEATURE_CORE_LOW (ARM_EXT_V7), 0xf910f000, 0xff70f000, "pli%c\t%a"}, @@ -2578,7 +2811,7 @@ static const struct opcode32 thumb32_opcodes[] = 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf7f0a000, 0xfff0f000, "udf%c.w\t%H"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xf3bf8f2f, 0xffffffff, "clrex%c"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"}, @@ -2606,9 +2839,9 @@ static const struct opcode32 thumb32_opcodes[] = 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"}, @@ -2626,7 +2859,7 @@ static const struct opcode32 thumb32_opcodes[] = 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"}, @@ -2734,7 +2967,7 @@ static const struct opcode32 thumb32_opcodes[] = 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4D, %16-19r"}, @@ -2802,7 +3035,7 @@ static const struct opcode32 thumb32_opcodes[] = 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"}, @@ -2850,11 +3083,11 @@ static const struct opcode32 thumb32_opcodes[] = 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"}, @@ -2876,7 +3109,7 @@ static const struct opcode32 thumb32_opcodes[] = 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"}, - {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M), 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2), 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"}, @@ -2969,18 +3202,20 @@ arm_regname; static const arm_regname regnames[] = { - { "raw" , "Select raw register names", + { "reg-names-raw", N_("Select raw register names"), { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}, - { "gcc", "Select register names used by GCC", + { "reg-names-gcc", N_("Select register names used by GCC"), { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }}, - { "std", "Select register names used in ARM's ISA documentation", + { "reg-names-std", N_("Select register names used in ARM's ISA documentation"), { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }}, - { "apcs", "Select register names used in the APCS", + { "force-thumb", N_("Assume all insns are Thumb insns"), {NULL} }, + { "no-force-thumb", N_("Examine preceding label to determine an insn's type"), {NULL} }, + { "reg-names-apcs", N_("Select register names used in the APCS"), { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }}, - { "atpcs", "Select register names used in the ATPCS", + { "reg-names-atpcs", N_("Select register names used in the ATPCS"), { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }}, - { "special-atpcs", "Select special register names used in the ATPCS", - { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}, + { "reg-names-special-atpcs", N_("Select special register names used in the ATPCS"), + { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }} }; static const char *const iwmmxt_wwnames[] = @@ -3006,7 +3241,7 @@ static const char *const iwmmxt_cregnames[] = /* Default to GCC register name set. */ static unsigned int regname_selected = 1; -#define NUM_ARM_REGNAMES NUM_ELEM (regnames) +#define NUM_ARM_OPTIONS ARRAY_SIZE (regnames) #define arm_regnames regnames[regname_selected].reg_names static bfd_boolean force_thumb = FALSE; @@ -3025,31 +3260,6 @@ static bfd_vma ifthen_address; /* Functions. */ -int -get_arm_regname_num_options (void) -{ - return NUM_ARM_REGNAMES; -} - -int -set_arm_regname_option (int option) -{ - int old = regname_selected; - regname_selected = option; - return old; -} - -int -get_arm_regnames (int option, - const char **setname, - const char **setdescription, - const char *const **register_names) -{ - *setname = regnames[option].name; - *setdescription = regnames[option].description; - *register_names = regnames[option].reg_names; - return 16; -} /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?. Returns pointer to following character of the format string and @@ -3064,8 +3274,8 @@ arm_decode_bitfield (const char *ptr, { unsigned long value = 0; int width = 0; - - do + + do { int start, end; int bits; @@ -3155,6 +3365,7 @@ print_insn_coprocessor (bfd_vma pc, unsigned long mask; unsigned long value = 0; int cond; + int cp_num; struct arm_private_data *private_data = info->private_data; arm_feature_set allowed_arches = ARM_ARCH_NONE; @@ -3193,6 +3404,8 @@ print_insn_coprocessor (bfd_vma pc, mask = insn->mask; value = insn->value; + cp_num = (given >> 8) & 0xf; + if (thumb) { /* The high 4 bits are 0xe for Arm conditional instructions, and @@ -3228,6 +3441,26 @@ print_insn_coprocessor (bfd_vma pc, if (! ARM_CPU_HAS_FEATURE (insn->arch, allowed_arches)) continue; + if (insn->value == 0xfe000010 /* mcr2 */ + || insn->value == 0xfe100010 /* mrc2 */ + || insn->value == 0xfc100000 /* ldc2 */ + || insn->value == 0xfc000000) /* stc2 */ + { + if (cp_num == 9 || cp_num == 10 || cp_num == 11) + is_unpredictable = TRUE; + } + else if (insn->value == 0x0e000000 /* cdp */ + || insn->value == 0xfe000000 /* cdp2 */ + || insn->value == 0x0e000010 /* mcr */ + || insn->value == 0x0e100010 /* mrc */ + || insn->value == 0x0c100000 /* ldc */ + || insn->value == 0x0c000000) /* stc */ + { + /* Floating-point instructions. */ + if (cp_num == 9 || cp_num == 10 || cp_num == 11) + continue; + } + for (c = insn->assembler; *c; c++) { if (*c == '%') @@ -3241,14 +3474,20 @@ print_insn_coprocessor (bfd_vma pc, case 'A': { int rn = (given >> 16) & 0xf; - bfd_vma offset = given & 0xff; + bfd_vma offset = given & 0xff; func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); if (PRE_BIT_SET || WRITEBACK_BIT_SET) { /* Not unindexed. The offset is scaled. */ - offset = offset * 4; + if (cp_num == 9) + /* vldr.16/vstr.16 will shift the address + left by 1 bit only. */ + offset = offset * 2; + else + offset = offset * 4; + if (NEGATIVE_BIT_SET) offset = - offset; if (rn != 15) @@ -3290,7 +3529,7 @@ print_insn_coprocessor (bfd_vma pc, func (stream, "\t; "); /* For unaligned PCs, apply off-by-alignment correction. */ - info->print_address_func (offset + pc + info->print_address_func (offset + pc + info->bytes_per_chunk * 2 - (pc & 3), info); @@ -3318,6 +3557,9 @@ print_insn_coprocessor (bfd_vma pc, /* Fall through. */ case 'c': + if (cond != COND_UNCOND && cp_num == 9) + is_unpredictable = TRUE; + func (stream, "%s", arm_conditional[cond]); break; @@ -3333,7 +3575,7 @@ print_insn_coprocessor (bfd_vma pc, /* Is ``imm'' a negative number? */ if (imm & 0x40) - imm |= (-1 << 7); + imm -= 0x80; func (stream, "%d", imm); } @@ -3435,10 +3677,15 @@ print_insn_coprocessor (bfd_vma pc, } func (stream, "%s", arm_regnames[value]); break; + case 'V': + if (given & (1 << 6)) + goto Q; + /* FALLTHROUGH */ case 'D': func (stream, "d%ld", value); break; case 'Q': + Q: if (value & 1) func (stream, "", value >> 1); else @@ -3448,6 +3695,36 @@ print_insn_coprocessor (bfd_vma pc, func (stream, "%ld", value); value_in_comment = value; break; + case 'E': + { + /* Converts immediate 8 bit back to float value. */ + unsigned floatVal = (value & 0x80) << 24 + | (value & 0x3F) << 19 + | ((value & 0x40) ? (0xF8 << 22) : (1 << 30)); + + /* Quarter float have a maximum value of 31.0. + Get floating point value multiplied by 1e7. + The maximum value stays in limit of a 32-bit int. */ + unsigned decVal = + (78125 << (((floatVal >> 23) & 0xFF) - 124)) * + (16 + (value & 0xF)); + + if (!(decVal % 1000000)) + func (stream, "%ld\t; 0x%08x %c%u.%01u", value, + floatVal, value & 0x80 ? '-' : ' ', + decVal / 10000000, + decVal % 10000000 / 1000000); + else if (!(decVal % 10000)) + func (stream, "%ld\t; 0x%08x %c%u.%03u", value, + floatVal, value & 0x80 ? '-' : ' ', + decVal / 10000000, + decVal % 10000000 / 10000); + else + func (stream, "%ld\t; 0x%08x %c%u.%07u", value, + floatVal, value & 0x80 ? '-' : ' ', + decVal / 10000000, decVal % 10000000); + break; + } case 'k': { int from = (given & (1 << 7)) ? 32 : 16; @@ -3847,7 +4124,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) else return FALSE; } - + for (insn = neon_opcodes; insn->assembler; insn++) { if ((given & insn->mask) == insn->value) @@ -3878,7 +4155,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) case 'A': { - static const unsigned char enc[16] = + static const unsigned char enc[16] = { 0x4, 0x14, /* st4 0,1 */ 0x4, /* st1 2 */ @@ -3900,7 +4177,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) int n = enc[type] & 0xf; int stride = (enc[type] >> 4) + 1; int ix; - + func (stream, "{"); if (stride > 1) for (ix = 0; ix != n; ix++) @@ -3919,7 +4196,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) func (stream, ", %s", arm_regnames[rm]); } break; - + case 'B': { int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); @@ -3935,7 +4212,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) if (length > 1 && size > 0) stride = (idx_align & (1 << size)) ? 2 : 1; - + switch (length) { case 1: @@ -3952,19 +4229,19 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) } } break; - + case 2: if (size == 2 && (idx_align & 2) != 0) return FALSE; align = (idx_align & 1) ? 16 << size : 0; break; - + case 3: if ((size == 2 && (idx_align & 3) != 0) || (idx_align & 1) != 0) return FALSE; break; - + case 4: if (size == 2) { @@ -3975,11 +4252,11 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) else align = (idx_align & 1) ? 32 << size : 0; break; - + default: abort (); } - + func (stream, "{"); for (i = 0; i < length; i++) func (stream, "%sd%d[%d]", (i == 0) ? "" : ",", @@ -3994,7 +4271,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) func (stream, ", %s", arm_regnames[rm]); } break; - + case 'C': { int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); @@ -4006,12 +4283,12 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) int n = type + 1; int stride = ((given >> 5) & 0x1); int ix; - + if (stride && (n == 1)) n++; else stride++; - + func (stream, "{"); if (stride > 1) for (ix = 0; ix != n; ix++) @@ -4038,18 +4315,18 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) func (stream, ", %s", arm_regnames[rm]); } break; - + case 'D': { int raw_reg = (given & 0xf) | ((given >> 1) & 0x10); int size = (given >> 20) & 3; int reg = raw_reg & ((4 << size) - 1); int ix = raw_reg >> size >> 2; - + func (stream, "d%d[%d]", reg, ix); } break; - + case 'E': /* Neon encoded constant for mov, mvn, vorr, vbic. */ { @@ -4060,11 +4337,11 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) unsigned shift; int size = 0; int isfloat = 0; - + bits |= ((given >> 24) & 1) << 7; bits |= ((given >> 16) & 7) << 4; bits |= ((given >> 0) & 15) << 0; - + if (cmode < 8) { shift = (cmode >> 1) & 3; @@ -4091,7 +4368,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) /* Bit replication into bytes. */ int ix; unsigned long mask; - + value = 0; hival = 0; for (ix = 7; ix >= 0; ix--) @@ -4115,7 +4392,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) { /* Floating point encoding. */ int tmp; - + value = (unsigned long) (bits & 0x7f) << 19; value |= (unsigned long) (bits & 0x80) << 24; tmp = bits & 0x40 ? 0x3c : 0x40; @@ -4135,7 +4412,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) case 8: func (stream, "#%ld\t; 0x%.2lx", value, value); break; - + case 16: func (stream, "#%ld\t; 0x%.4lx", value, value); break; @@ -4145,24 +4422,24 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) { unsigned char valbytes[4]; double fvalue; - + /* Do this a byte at a time so we don't have to worry about the host's endianness. */ valbytes[0] = value & 0xff; valbytes[1] = (value >> 8) & 0xff; valbytes[2] = (value >> 16) & 0xff; valbytes[3] = (value >> 24) & 0xff; - - floatformat_to_double + + floatformat_to_double (& floatformat_ieee_single_little, valbytes, & fvalue); - + func (stream, "#%.7g\t; 0x%.8lx", fvalue, value); } else func (stream, "#%ld\t; 0x%.8lx", - (long) (((value & 0x80000000L) != 0) + (long) (((value & 0x80000000L) != 0) ? value | ~0xffffffffL : value), value); break; @@ -4170,18 +4447,18 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) case 64: func (stream, "#0x%.8lx%.8lx", hival, value); break; - + default: abort (); } } break; - + case 'F': { int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10); int num = (given >> 8) & 0x3; - + if (!num) func (stream, "{d%d}", regno); else if (num + regno >= 32) @@ -4199,7 +4476,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) unsigned long value; c = arm_decode_bitfield (c, given, &value, &width); - + switch (*c) { case 'r': @@ -4212,7 +4489,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) case 'e': func (stream, "%ld", (1ul << width) - value); break; - + case 'S': case 'T': case 'U': @@ -4252,7 +4529,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) else func (stream, "q%ld", value >> 1); break; - + case '`': c++; if (value == 0) @@ -4295,20 +4572,20 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) /* Return the name of a v7A special register. */ -static const char * +static const char * banked_regname (unsigned reg) { switch (reg) { case 15: return "CPSR"; - case 32: return "R8_usr"; + case 32: return "R8_usr"; case 33: return "R9_usr"; case 34: return "R10_usr"; case 35: return "R11_usr"; case 36: return "R12_usr"; case 37: return "SP_usr"; case 38: return "LR_usr"; - case 40: return "R8_fiq"; + case 40: return "R8_fiq"; case 41: return "R9_fiq"; case 42: return "R10_fiq"; case 43: return "R11_fiq"; @@ -4422,6 +4699,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) case 'S': allow_unpredictable = TRUE; + /* Fall through. */ case 's': if ((given & 0x004f0000) == 0x004f0000) { @@ -4605,6 +4883,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) if (! ARM_CPU_HAS_FEATURE (private_data->features, \ arm_ext_v6)) func (stream, "p"); + else + is_unpredictable = TRUE; } break; @@ -4689,7 +4969,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) } else { - func (stream, "%cPSR_", + func (stream, "%cPSR_", (given & 0x00400000) ? 'S' : 'C'); if (given & 0x80000) func (stream, "f"); @@ -4703,7 +4983,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) break; case 'U': - if ((given & 0xf0) == 0x60) + if ((given & 0xf0) == 0x60) { switch (given & 0xf) { @@ -4712,8 +4992,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) func (stream, "#%d", (int) given & 0xf); break; } - } - else + } + else { const char * opt = data_barrier_option (given & 0xf); if (opt != NULL) @@ -4730,7 +5010,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) unsigned long value; c = arm_decode_bitfield (c, given, &value, &width); - + switch (*c) { case 'R': @@ -5161,20 +5441,31 @@ 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_MAX"; - case 19: return "FAULTMASK"; - case 20: return "CONTROL"; + case 0x0: return "APSR"; + case 0x1: return "IAPSR"; + case 0x2: return "EAPSR"; + case 0x3: return "PSR"; + case 0x5: return "IPSR"; + case 0x6: return "EPSR"; + case 0x7: return "IEPSR"; + case 0x8: return "MSP"; + case 0x9: return "PSP"; + case 0xa: return "MSPLIM"; + case 0xb: return "PSPLIM"; + case 0x10: return "PRIMASK"; + case 0x11: return "BASEPRI"; + case 0x12: return "BASEPRI_MAX"; + case 0x13: return "FAULTMASK"; + case 0x14: return "CONTROL"; + case 0x88: return "MSP_NS"; + case 0x89: return "PSP_NS"; + case 0x8a: return "MSPLIM_NS"; + case 0x8b: return "PSPLIM_NS"; + case 0x90: return "PRIMASK_NS"; + case 0x91: return "BASEPRI_NS"; + case 0x93: return "FAULTMASK_NS"; + case 0x94: return "CONTROL_NS"; + case 0x98: return "SP_NS"; default: return ""; } } @@ -5267,7 +5558,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) value_in_comment = imm; } break; - + case 'J': { unsigned int imm = 0; @@ -5449,7 +5740,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) if (off || !U) { func (stream, ", #%c%u", U ? '+' : '-', off * 4); - value_in_comment = off * 4 * U ? 1 : -1; + value_in_comment = off * 4 * (U ? 1 : -1); } func (stream, "]"); if (W) @@ -5461,7 +5752,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) if (W) { func (stream, "#%c%u", U ? '+' : '-', off * 4); - value_in_comment = off * 4 * U ? 1 : -1; + value_in_comment = off * 4 * (U ? 1 : -1); } else { @@ -5597,7 +5888,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) break; case 'U': - if ((given & 0xf0) == 0x60) + if ((given & 0xf0) == 0x60) { switch (given & 0xf) { @@ -5607,7 +5898,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) break; } } - else + else { const char * opt = data_barrier_option (given & 0xf); if (opt != NULL) @@ -5638,7 +5929,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) sysm |= (given & 0x30); sysm |= (given & 0x00100000) >> 14; name = banked_regname (sysm); - + if (name != NULL) func (stream, "%s", name); else @@ -5677,7 +5968,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) unsigned long val; c = arm_decode_bitfield (c, given, &val, &width); - + switch (*c) { case 'd': @@ -5695,10 +5986,6 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) value_in_comment = val * 4; break; - case 'S': - if (val == 13) - is_unpredictable = TRUE; - /* Fall through. */ case 'R': if (val == 15) is_unpredictable = TRUE; @@ -5716,7 +6003,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) if (val == ((1ul << width) - 1)) func (stream, "%c", *c); break; - + case '`': c++; if (val == 0) @@ -5727,7 +6014,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) func (stream, "%c", c[(1 << width) - (int) val]); c += 1 << width; break; - + case 'x': func (stream, "0x%lx", val & 0xffffffffUL); break; @@ -5805,7 +6092,7 @@ arm_symbol_is_valid (asymbol * sym, struct disassemble_info * info ATTRIBUTE_UNUSED) { const char * name; - + if (sym == NULL) return FALSE; @@ -5814,63 +6101,42 @@ arm_symbol_is_valid (asymbol * sym, return (name && *name != '$' && strncmp (name, "__tagsym$$", 10)); } -/* Parse an individual disassembler option. */ +/* Parse the string of disassembler options. */ -void -parse_arm_disassembler_option (char *option) +static void +parse_arm_disassembler_options (const char *options) { - if (option == NULL) - return; + const char *opt; - if (CONST_STRNEQ (option, "reg-names-")) + FOR_EACH_DISASSEMBLER_OPTION (opt, options) { - int i; - - option += 10; - - for (i = NUM_ARM_REGNAMES; i--;) - if (strneq (option, regnames[i].name, strlen (regnames[i].name))) - { - regname_selected = i; - break; - } + if (CONST_STRNEQ (opt, "reg-names-")) + { + unsigned int i; + for (i = 0; i < NUM_ARM_OPTIONS; i++) + if (disassembler_options_cmp (opt, regnames[i].name) == 0) + { + regname_selected = i; + break; + } - if (i < 0) - /* XXX - should break 'option' at following delimiter. */ - fprintf (stderr, _("Unrecognised register name set: %s\n"), option); + if (i >= NUM_ARM_OPTIONS) + fprintf (stderr, _("Unrecognised register name set: %s\n"), opt); + } + else if (CONST_STRNEQ (opt, "force-thumb")) + force_thumb = 1; + else if (CONST_STRNEQ (opt, "no-force-thumb")) + force_thumb = 0; + else + fprintf (stderr, _("Unrecognised disassembler option: %s\n"), opt); } - else if (CONST_STRNEQ (option, "force-thumb")) - force_thumb = 1; - else if (CONST_STRNEQ (option, "no-force-thumb")) - force_thumb = 0; - else - /* XXX - should break 'option' at following delimiter. */ - fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); return; } -/* Parse the string of disassembler options, spliting it at whitespaces - or commas. (Whitespace separators supported for backwards compatibility). */ - -static void -parse_disassembler_options (char *options) -{ - if (options == NULL) - return; - - while (*options) - { - parse_arm_disassembler_option (options); - - /* Skip forward to next seperator. */ - while ((*options) && (! ISSPACE (*options)) && (*options != ',')) - ++ options; - /* Skip forward past seperators. */ - while (ISSPACE (*options) || (*options == ',')) - ++ options; - } -} +static bfd_boolean +mapping_symbol_for_insn (bfd_vma pc, struct disassemble_info *info, + enum map_type *map_symbol); /* Search back through the insn stream to determine if this instruction is conditionally executed. */ @@ -5934,9 +6200,15 @@ find_ifthen_state (bfd_vma pc, } if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0) { - /* This could be an IT instruction. */ - seen_it = insn; - it_count = count >> 1; + enum map_type type = MAP_ARM; + bfd_boolean found = mapping_symbol_for_insn (addr, info, &type); + + if (!found || (found && type == MAP_THUMB)) + { + /* This could be an IT instruction. */ + seen_it = insn; + it_count = count >> 1; + } } if ((insn & 0xf800) >= 0xe800) count++; @@ -6010,7 +6282,8 @@ get_sym_code_type (struct disassemble_info *info, /* If the symbol has function type then use that. */ if (type == STT_FUNC || type == STT_GNU_IFUNC) { - if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB) + if (ARM_GET_SYM_BRANCH_TYPE (es->internal_elf_sym.st_target_internal) + == ST_BRANCH_TO_THUMB) *map_type = MAP_THUMB; else *map_type = MAP_ARM; @@ -6020,6 +6293,71 @@ get_sym_code_type (struct disassemble_info *info, return FALSE; } +/* Search the mapping symbol state for instruction at pc. This is only + applicable for elf target. + + There is an assumption Here, info->private_data contains the correct AND + up-to-date information about current scan process. The information will be + used to speed this search process. + + Return TRUE if the mapping state can be determined, and map_symbol + will be updated accordingly. Otherwise, return FALSE. */ + +static bfd_boolean +mapping_symbol_for_insn (bfd_vma pc, struct disassemble_info *info, + enum map_type *map_symbol) +{ + bfd_vma addr; + int n, start = 0; + bfd_boolean found = FALSE; + enum map_type type = MAP_ARM; + struct arm_private_data *private_data; + + if (info->private_data == NULL || info->symtab_size == 0 + || bfd_asymbol_flavour (*info->symtab) != bfd_target_elf_flavour) + return FALSE; + + private_data = info->private_data; + if (pc == 0) + start = 0; + else + start = private_data->last_mapping_sym; + + start = (start == -1)? 0 : start; + addr = bfd_asymbol_value (info->symtab[start]); + + if (pc >= addr) + { + if (get_map_sym_type (info, start, &type)) + found = TRUE; + } + else + { + for (n = start - 1; n >= 0; n--) + { + if (get_map_sym_type (info, n, &type)) + { + found = TRUE; + break; + } + } + } + + /* No mapping symbols were found. A leading $d may be + omitted for sections which start with data; but for + compatibility with legacy and stripped binaries, only + assume the leading $d if there is at least one mapping + symbol in the file. */ + if (!found && private_data->has_mapping_symbols == 1) + { + type = MAP_DATA; + found = TRUE; + } + + *map_symbol = type; + return found; +} + /* Given a bfd_mach_arm_XXX value, this function fills in the fields of the supplied arm_feature_set structure with bitmasks indicating the support base architectures and coprocessor extensions. @@ -6087,7 +6425,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little) if (info->disassembler_options) { - parse_disassembler_options (info->disassembler_options); + parse_arm_disassembler_options (info->disassembler_options); /* To avoid repeated parsing of these options, we remove them here. */ info->disassembler_options = NULL; @@ -6101,7 +6439,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little) if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0) /* If the user did not use the -m command line switch then default to disassembling all types of ARM instruction. - + The info->mach value has to be ignored as this will be based on the default archictecture for the target and/or hints in the notes section, but it will never be greater than the current largest arm @@ -6151,7 +6489,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little) we finished last time. */ /* PR 14006. When the address is 0 we are either at the start of the very first function, or else the first function in a new, unlinked - executable section (eg because uf -ffunction-sections). Either way + executable section (eg because of -ffunction-sections). Either way start scanning from the beginning of the symbol table, not where we left off last time. */ if (pc == 0) @@ -6312,9 +6650,16 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little) es = *(elf_symbol_type **)(info->symbols); type = ELF_ST_TYPE (es->internal_elf_sym.st_info); - is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) - == ST_BRANCH_TO_THUMB) - || type == STT_ARM_16BIT); + is_thumb = + ((ARM_GET_SYM_BRANCH_TYPE (es->internal_elf_sym.st_target_internal) + == ST_BRANCH_TO_THUMB) || type == STT_ARM_16BIT); + } + else if (bfd_asymbol_flavour (*info->symbols) + == bfd_target_mach_o_flavour) + { + bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)*info->symbols; + + is_thumb = (asym->n_desc & BFD_MACH_O_N_ARM_THUMB_DEF); } } @@ -6449,21 +6794,51 @@ print_insn_little_arm (bfd_vma pc, struct disassemble_info *info) return print_insn (pc, info, TRUE); } +const disasm_options_t * +disassembler_options_arm (void) +{ + static disasm_options_t *opts = NULL; + + if (opts == NULL) + { + unsigned int i; + opts = XNEW (disasm_options_t); + opts->name = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1); + opts->description = XNEWVEC (const char *, NUM_ARM_OPTIONS + 1); + for (i = 0; i < NUM_ARM_OPTIONS; i++) + { + opts->name[i] = regnames[i].name; + if (regnames[i].description != NULL) + opts->description[i] = _(regnames[i].description); + else + opts->description[i] = NULL; + } + /* The array we return must be NULL terminated. */ + opts->name[i] = NULL; + opts->description[i] = NULL; + } + + return opts; +} + void print_arm_disassembler_options (FILE *stream) { - int i; - + unsigned int i, max_len = 0; fprintf (stream, _("\n\ The following ARM specific disassembler options are supported for use with\n\ the -M switch:\n")); - for (i = NUM_ARM_REGNAMES; i--;) - fprintf (stream, " reg-names-%s %*c%s\n", - regnames[i].name, - (int)(14 - strlen (regnames[i].name)), ' ', - regnames[i].description); + for (i = 0; i < NUM_ARM_OPTIONS; i++) + { + unsigned int len = strlen (regnames[i].name); + if (max_len < len) + max_len = len; + } - fprintf (stream, " force-thumb Assume all insns are Thumb insns\n"); - fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n"); + for (i = 0, max_len++; i < NUM_ARM_OPTIONS; i++) + fprintf (stream, " %s%*c %s\n", + regnames[i].name, + (int)(max_len - strlen (regnames[i].name)), ' ', + _(regnames[i].description)); }