diff --git a/gas/ChangeLog b/gas/ChangeLog index 17fa42e700..6a7cab6c12 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2015-12-14 Matthew Wahab + + * config/tc-aarch64.c (parse_neon_type_for_operand): Adjust to + take into account new vector type 2H. + (vectype_to_qualifier): Likewise. + 2015-12-14 Matthew Wahab * config/tc-aarch64.c (vectype_to_qualifier): Calculate operand diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 0e47189172..253f3be3a7 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -744,7 +744,7 @@ aarch64_reg_parse_32_64 (char **ccp, int reject_sp, int reject_rz, otherwise return FALSE. Accept only one occurrence of: - 8b 16b 4h 8h 2s 4s 1d 2d + 8b 16b 2h 4h 8h 2s 4s 1d 2d b h s d q */ static bfd_boolean parse_neon_type_for_operand (struct neon_type_el *parsed_type, char **str) @@ -803,7 +803,8 @@ elt_size: first_error (_("missing element size")); return FALSE; } - if (width != 0 && width * element_size != 64 && width * element_size != 128) + if (width != 0 && width * element_size != 64 && width * element_size != 128 + && !(width == 2 && element_size == 16)) { first_error_fmt (_ ("invalid element size %d and vector size combination %c"), @@ -4674,7 +4675,7 @@ vectype_to_qualifier (const struct neon_type_el *vectype) const unsigned int ele_base [5] = { AARCH64_OPND_QLF_V_8B, - AARCH64_OPND_QLF_V_4H, + AARCH64_OPND_QLF_V_2H, AARCH64_OPND_QLF_V_2S, AARCH64_OPND_QLF_V_1D, AARCH64_OPND_QLF_V_1Q @@ -4694,7 +4695,7 @@ vectype_to_qualifier (const struct neon_type_el *vectype) int reg_size = ele_size[vectype->type] * vectype->width; unsigned offset; unsigned shift; - if (reg_size != 16 && reg_size != 8) + if (reg_size != 16 && reg_size != 8 && reg_size != 4) goto vectype_conversion_fail; /* The conversion is by calculating the offset from the base operand @@ -4704,9 +4705,7 @@ vectype_to_qualifier (const struct neon_type_el *vectype) shift = 0; if (vectype->type == NT_b) shift = 4; - else if (vectype->type == NT_h) - shift = 3; - else if (vectype->type == NT_s) + else if (vectype->type == NT_h || vectype->type == NT_s) shift = 2; else if (vectype->type >= NT_d) shift = 1; diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index f307a2aa76..e72c1a03de 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,8 @@ +2015-12-14 Matthew Wahab + + * aarch64.h (enum aarch64_opnd_qualifier): Add + AARCH64_OPND_QLF_V_2H. + 2015-12-11 Matthew Wahab * aarch64.h (aarch64_opnd): Add AARCH64_OPND_BARRIER_PSB. diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index b8a2c0142a..80c91d3489 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -282,6 +282,7 @@ enum aarch64_opnd_qualifier constraint qualifiers for immediate operands wherever possible. */ AARCH64_OPND_QLF_V_8B, AARCH64_OPND_QLF_V_16B, + AARCH64_OPND_QLF_V_2H, AARCH64_OPND_QLF_V_4H, AARCH64_OPND_QLF_V_8H, AARCH64_OPND_QLF_V_2S, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 9bfaea28bf..70a7195e8a 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2015-12-14 Matthew Wahab + + * aarch64-dis.c (get_vreg_qualifier_from_value): Update comment + and adjust calculation to ignore qualifier for type 2H. + * aarch64-opc.c (aarch64_opnd_qualifier): Add "2H". + 2015-12-14 Matthew Wahab * aarch64-asm-2.c: Regenerate. diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 6763c36059..647ce0d0ba 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -173,12 +173,19 @@ get_greg_qualifier_from_value (aarch64_insn value) return qualifier; } -/* Given VALUE, return qualifier for a vector register. */ +/* Given VALUE, return qualifier for a vector register. This does not support + decoding instructions that accept the 2H vector type. */ + static inline enum aarch64_opnd_qualifier get_vreg_qualifier_from_value (aarch64_insn value) { enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value; + /* Instructions using vector type 2H should not call this function. Skip over + the 2H qualifier. */ + if (qualifier >= AARCH64_OPND_QLF_V_2H) + qualifier += 1; + assert (value <= 0x8 && aarch64_get_qualifier_standard_value (qualifier) == value); return qualifier; diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index 88c4a284df..28b991cfe1 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -578,6 +578,7 @@ struct operand_qualifier_data aarch64_opnd_qualifiers[] = {1, 8, 0x0, "8b", OQK_OPD_VARIANT}, {1, 16, 0x1, "16b", OQK_OPD_VARIANT}, + {2, 2, 0x0, "2h", OQK_OPD_VARIANT}, {2, 4, 0x2, "4h", OQK_OPD_VARIANT}, {2, 8, 0x3, "8h", OQK_OPD_VARIANT}, {4, 2, 0x4, "2s", OQK_OPD_VARIANT},