0xee800040, 0xef800840,
"cx3d%a\t%p, %0-3S, %0-3T, %16-19n, %12-15n, #%4-5,7,20-22d"),
+ CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+ 0xec200000, 0xeeb00840,
+ "vcx1%a\t%p, %12-15,22V, #%0-5,7,16-19d"),
+ CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+ 0xec200040, 0xeeb00840,
+ "vcx1%a\t%p, %12-15,22V, #%0-5,7,16-19,24d"),
+
+ CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+ 0xec300000, 0xeeb00840,
+ "vcx2%a\t%p, %12-15,22V, %0-3,5V, #%4,7,16-19d"),
+ CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+ 0xec300040, 0xeeb00840,
+ "vcx2%a\t%p, %12-15,22V, %0-3,5V, #%4,7,16-19,24d"),
+
+ CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+ 0xec800000, 0xee800840,
+ "vcx3%a\t%p, %12-15,22V, %16-19,7V, %0-3,5V, #%4,20-21d"),
+ CDE_OPCODE (ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE),
+ 0xec800040, 0xee800840,
+ "vcx3%a\t%p, %12-15,22V, %16-19,7V, %0-3,5V, #%4,20-21,24d"),
+
CDE_OPCODE (ARM_FEATURE_CORE_LOW (0), 0, 0, 0)
};
/* Data transfer between ARM and NEON registers. */
{ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
- 0x0e800b10, 0x1ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
+ 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
{ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
- 0x0e800b30, 0x1ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
+ 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
{ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
- 0x0ea00b10, 0x1ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
+ 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
{ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
- 0x0ea00b30, 0x1ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
+ 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
{ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
- 0x0ec00b10, 0x1ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
+ 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
{ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
- 0x0ee00b10, 0x1ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
+ 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
/* Move data element to all lanes. */
{ARM_FEATURE_COPROC (FPU_NEON_EXT_V1),
func (stream, "%ld", value);
break;
+ case 'V':
+ if (given & (1 << 6))
+ func (stream, "q%ld", value >> 1);
+ else if (given & (1 << 24))
+ func (stream, "d%ld", value);
+ else
+ {
+ /* Encoding for S register is different than for D and
+ Q registers. S registers are encoded using the top
+ single bit in position 22 as the lowest bit of the
+ register number, while for Q and D it represents the
+ highest bit of the register number. */
+ uint8_t top_bit = (value >> 4) & 1;
+ uint8_t tmp = (value << 1) & 0x1e;
+ uint8_t res = tmp | top_bit;
+ func (stream, "s%u", res);
+ }
+ break;
+
default:
abort ();
}
|| (given & 0xff000000) == 0xfc000000)
;
/* vdup is also a valid neon instruction. */
- else if ((given & 0xff910f5f) != 0xee800b10)
+ else if ((given & 0xff900f5f) != 0xee800b10)
return FALSE;
}
for (insn = neon_opcodes; insn->assembler; insn++)
{
- if ((given & insn->mask) == insn->value)
+ unsigned long cond_mask = insn->mask;
+ unsigned long cond_value = insn->value;
+ int cond;
+
+ if (thumb)
+ {
+ if ((cond_mask & 0xf0000000) == 0) {
+ /* For the entries in neon_opcodes, an opcode mask/value with
+ the high 4 bits equal to 0 indicates a conditional
+ instruction. For thumb however, we need to include those
+ bits in the instruction matching. */
+ cond_mask |= 0xf0000000;
+ /* Furthermore, the thumb encoding of a conditional instruction
+ will have the high 4 bits equal to 0xe. */
+ cond_value |= 0xe0000000;
+ }
+ if (ifthen_state)
+ cond = IFTHEN_COND;
+ else
+ cond = COND_UNCOND;
+ }
+ else
+ {
+ if ((given & 0xf0000000) == 0xf0000000)
+ {
+ /* If the instruction is unconditional, update the mask to only
+ match against unconditional opcode values. */
+ cond_mask |= 0xf0000000;
+ cond = COND_UNCOND;
+ }
+ else
+ {
+ cond = (given >> 28) & 0xf;
+ if (cond == 0xe)
+ cond = COND_UNCOND;
+ }
+ }
+
+ if ((given & cond_mask) == cond_value)
{
signed long value_in_comment = 0;
bfd_boolean is_unpredictable = FALSE;
/* Fall through. */
case 'c':
- if (thumb && ifthen_state)
- func (stream, "%s", arm_conditional[IFTHEN_COND]);
+ func (stream, "%s", arm_conditional[cond]);
break;
case 'A':