X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=opcodes%2Faarch64-dis.c;h=7bd2c49aee39e724f3cce375cd2fa965f9c06718;hb=f5df0b5f0874598790a60f1462f67887868bd77f;hp=5571ab6c98fdfebb156977bfa5e0f82fe83d853b;hpb=3c17238bc9fe8a078a6199470291f07bab9c64c8;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 5571ab6c98..7bd2c49aee 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -1,5 +1,5 @@ /* aarch64-dis.c -- AArch64 disassembler. - Copyright (C) 2009-2019 Free Software Foundation, Inc. + Copyright (C) 2009-2020 Free Software Foundation, Inc. Contributed by ARM Ltd. This file is part of the GNU opcodes library. @@ -178,18 +178,15 @@ extract_all_fields (const aarch64_operand *self, aarch64_insn code) } /* Sign-extend bit I of VALUE. */ -static inline int32_t +static inline uint64_t sign_extend (aarch64_insn value, unsigned i) { - uint32_t ret = value; + uint64_t ret, sign; assert (i < 32); - if ((value >> i) & 0x1) - { - uint32_t val = (uint32_t)(-1) << i; - ret = ret | val; - } - return (int32_t) ret; + ret = value; + sign = (uint64_t) 1 << i; + return ((ret & (sign + sign - 1)) ^ sign) - sign; } /* N.B. the following inline helpfer functions create a dependency on the @@ -348,6 +345,7 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, switch (info->qualifier) { case AARCH64_OPND_QLF_S_4B: + case AARCH64_OPND_QLF_S_2H: /* L:H */ info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L); info->reglane.regno &= 0x1f; @@ -657,7 +655,7 @@ aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_inst *inst ATTRIBUTE_UNUSED, aarch64_operand_error *errors ATTRIBUTE_UNUSED) { - int64_t imm; + uint64_t imm; imm = extract_all_fields (self, code); @@ -2822,14 +2820,35 @@ aarch64_decode_variant_using_iclass (aarch64_inst *inst) variant = i - 1; break; - case sve_size_013: - i = extract_field (FLD_size, inst->value, 0); - if (i == 2) + case sve_size_13: + /* Ignore low bit of this field since that is set in the opcode for + instructions of this iclass. */ + i = (extract_field (FLD_size, inst->value, 0) & 2); + variant = (i >> 1); + break; + + case sve_shift_tsz_bhsd: + i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19); + if (i == 0) return FALSE; - if (i == 3) - variant = 2; - else - variant = i; + while (i != 1) + { + i >>= 1; + variant += 1; + } + break; + + case sve_size_tsz_bhs: + i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19); + if (i == 0) + return FALSE; + while (i != 1) + { + if (i & 1) + return FALSE; + i >>= 1; + variant += 1; + } break; case sve_shift_tsz_hsd: