X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Farm-dis.c;h=87d4930b30fd9fef9880dbe803abaafc583c27a2;hb=9889cbb14ebea4b281408afcfd94ad6646ab370a;hp=e9f4425a152e5f0a53ce3cc12de54d5bac78fb4c;hpb=d6b4b13ed2859a1eafd6c94c0dc64b20fdbde1ba;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index e9f4425a15..87d4930b30 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-2016 Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Modification by James G. Smith (jsmith@cygnus.co.uk) @@ -34,6 +34,7 @@ #include "elf-bfd.h" #include "elf/internal.h" #include "elf/arm.h" +#include "mach-o.h" /* FIXME: Belongs in global header. */ #ifndef strneq @@ -115,6 +116,7 @@ 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 + %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 +126,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 +408,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"}, @@ -578,9 +586,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 +826,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 +846,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, "" }, @@ -889,6 +897,80 @@ 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"}, + {ARM_FEATURE_CORE_LOW (0), 0, 0, 0} }; @@ -919,7 +1001,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 +1038,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 +1094,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 +1139,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 +1161,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 +1185,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), @@ -1350,6 +1487,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), @@ -1409,19 +1549,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), @@ -1431,15 +1577,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), @@ -1538,10 +1690,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 @@ -1574,39 +1726,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"}, @@ -1646,6 +1802,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), @@ -1662,9 +1820,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"}, @@ -2123,11 +2281,13 @@ 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_V5), + 0x0130f000, 0x0ff0f010, "bx%c\t%0-3r"}, {ARM_FEATURE_CORE_LOW (ARM_EXT_V1), 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"}, @@ -2276,6 +2436,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), @@ -2313,6 +2475,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"}, @@ -2327,8 +2493,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. */ @@ -2516,6 +2684,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"}, @@ -2597,7 +2780,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"}, @@ -2625,9 +2808,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"}, @@ -2645,7 +2828,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]"}, @@ -2753,7 +2936,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"}, @@ -2821,7 +3004,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"}, @@ -2869,11 +3052,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"}, @@ -2895,7 +3078,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"}, @@ -3083,8 +3266,8 @@ arm_decode_bitfield (const char *ptr, { unsigned long value = 0; int width = 0; - - do + + do { int start, end; int bits; @@ -3174,6 +3357,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; @@ -3212,6 +3396,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 @@ -3247,6 +3433,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 == '%') @@ -3260,14 +3466,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) @@ -3309,7 +3521,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); @@ -3337,6 +3549,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; @@ -3352,7 +3567,7 @@ print_insn_coprocessor (bfd_vma pc, /* Is ``imm'' a negative number? */ if (imm & 0x40) - imm |= (-1 << 7); + imm -= 0x80; func (stream, "%d", imm); } @@ -3467,6 +3682,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; @@ -3866,7 +4111,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) @@ -3897,7 +4142,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 */ @@ -3919,7 +4164,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++) @@ -3938,7 +4183,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); @@ -3954,7 +4199,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: @@ -3971,19 +4216,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) { @@ -3994,11 +4239,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) ? "" : ",", @@ -4013,7 +4258,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); @@ -4025,12 +4270,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++) @@ -4057,18 +4302,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. */ { @@ -4079,11 +4324,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; @@ -4110,7 +4355,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--) @@ -4134,7 +4379,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; @@ -4154,7 +4399,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; @@ -4164,24 +4409,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; @@ -4189,18 +4434,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) @@ -4218,7 +4463,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': @@ -4231,7 +4476,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': @@ -4271,7 +4516,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) @@ -4314,20 +4559,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"; @@ -4441,6 +4686,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) { @@ -4624,6 +4870,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; @@ -4708,7 +4956,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"); @@ -4722,7 +4970,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) { @@ -4731,8 +4979,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) @@ -4749,7 +4997,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': @@ -5180,20 +5428,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 ""; } } @@ -5286,7 +5545,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) value_in_comment = imm; } break; - + case 'J': { unsigned int imm = 0; @@ -5616,7 +5875,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) { @@ -5626,7 +5885,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) @@ -5657,7 +5916,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 @@ -5696,7 +5955,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': @@ -5735,7 +5994,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) @@ -5746,7 +6005,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; @@ -5824,7 +6083,7 @@ arm_symbol_is_valid (asymbol * sym, struct disassemble_info * info ATTRIBUTE_UNUSED) { const char * name; - + if (sym == NULL) return FALSE; @@ -5887,10 +6146,14 @@ parse_disassembler_options (char *options) ++ options; /* Skip forward past seperators. */ while (ISSPACE (*options) || (*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. */ @@ -5953,9 +6216,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++; @@ -6029,7 +6298,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; @@ -6039,6 +6309,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. @@ -6120,7 +6455,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 @@ -6170,7 +6505,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) @@ -6331,9 +6666,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); } }