aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-aarch64.c36
2 files changed, 35 insertions, 6 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 28e8984..17fa42e 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2015-12-14 Matthew Wahab <matthew.wahab@arm.com>
+
+ * config/tc-aarch64.c (vectype_to_qualifier): Calculate operand
+ qualifier from per-type base and offet.
+
2015-12-14 Jan Beulich <jbeulich@suse.com>
* dw2gencfi.c (dot_cfi_label): Free "name".
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 2685ae8..0e47189 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -4671,6 +4671,14 @@ vectype_to_qualifier (const struct neon_type_el *vectype)
/* Element size in bytes indexed by neon_el_type. */
const unsigned char ele_size[5]
= {1, 2, 4, 8, 16};
+ const unsigned int ele_base [5] =
+ {
+ AARCH64_OPND_QLF_V_8B,
+ AARCH64_OPND_QLF_V_4H,
+ AARCH64_OPND_QLF_V_2S,
+ AARCH64_OPND_QLF_V_1D,
+ AARCH64_OPND_QLF_V_1Q
+ };
if (!vectype->defined || vectype->type == NT_invtype)
goto vectype_conversion_fail;
@@ -4685,14 +4693,30 @@ vectype_to_qualifier (const struct neon_type_el *vectype)
/* Vector register. */
int reg_size = ele_size[vectype->type] * vectype->width;
unsigned offset;
+ unsigned shift;
if (reg_size != 16 && reg_size != 8)
goto vectype_conversion_fail;
- /* The conversion is calculated based on the relation of the order of
- qualifiers to the vector element size and vector register size. */
- offset = (vectype->type == NT_q)
- ? 8 : (vectype->type << 1) + (reg_size >> 4);
- gas_assert (offset <= 8);
- return AARCH64_OPND_QLF_V_8B + offset;
+
+ /* The conversion is by calculating the offset from the base operand
+ qualifier for the vector type. The operand qualifiers are regular
+ enough that the offset can established by shifting the vector width by
+ a vector-type dependent amount. */
+ shift = 0;
+ if (vectype->type == NT_b)
+ shift = 4;
+ else if (vectype->type == NT_h)
+ shift = 3;
+ else if (vectype->type == NT_s)
+ shift = 2;
+ else if (vectype->type >= NT_d)
+ shift = 1;
+ else
+ gas_assert (0);
+
+ offset = ele_base [vectype->type] + (vectype->width >> shift);
+ gas_assert (AARCH64_OPND_QLF_V_8B <= offset
+ && offset <= AARCH64_OPND_QLF_V_1Q);
+ return offset;
}
vectype_conversion_fail: