diff options
Diffstat (limited to 'binutils-2.25/opcodes/aarch64-dis.c')
-rw-r--r-- | binutils-2.25/opcodes/aarch64-dis.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/binutils-2.25/opcodes/aarch64-dis.c b/binutils-2.25/opcodes/aarch64-dis.c index c403be85..589fa842 100644 --- a/binutils-2.25/opcodes/aarch64-dis.c +++ b/binutils-2.25/opcodes/aarch64-dis.c @@ -1,5 +1,5 @@ /* aarch64-dis.c -- AArch64 disassembler. - Copyright 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2009-2014 Free Software Foundation, Inc. Contributed by ARM Ltd. This file is part of the GNU opcodes library. @@ -224,6 +224,17 @@ aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info, return 1; } +int +aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, + const aarch64_insn code ATTRIBUTE_UNUSED, + const aarch64_inst *inst ATTRIBUTE_UNUSED) +{ + assert (info->idx == 1 + || info->idx ==3); + info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1; + return 1; +} + /* e.g. IC <ic_op>{, <Xt>}. */ int aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info, @@ -422,11 +433,17 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, info->reglist.index = QSsize; break; case 0x1: + if (QSsize & 0x1) + /* UND. */ + return 0; info->qualifier = AARCH64_OPND_QLF_S_H; /* Index encoded in "Q:S:size<1>". */ info->reglist.index = QSsize >> 1; break; case 0x2: + if ((QSsize >> 1) & 0x1) + /* UND. */ + return 0; if ((QSsize & 0x1) == 0) { info->qualifier = AARCH64_OPND_QLF_S_S; @@ -435,12 +452,12 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, } else { - info->qualifier = AARCH64_OPND_QLF_S_D; - /* Index encoded in "Q". */ - info->reglist.index = QSsize >> 3; if (extract_field (FLD_S, code, 0)) /* UND */ return 0; + info->qualifier = AARCH64_OPND_QLF_S_D; + /* Index encoded in "Q". */ + info->reglist.index = QSsize >> 3; } break; default: @@ -1354,6 +1371,13 @@ do_special_decoding (aarch64_inst *inst) && extract_field (FLD_N, inst->value, 0) != value) return 0; } + /* 'sf' field. */ + if (inst->opcode->flags & F_LSE_SZ) + { + idx = select_operand_for_sf_field_coding (inst->opcode); + value = extract_field (FLD_lse_sz, inst->value, 0); + inst->operands[idx].qualifier = get_greg_qualifier_from_value (value); + } /* size:Q fields. */ if (inst->opcode->flags & F_SIZEQ) return decode_sizeq (inst); @@ -1601,12 +1625,14 @@ convert_ubfm_to_lsl (aarch64_inst *inst) /* CINC <Wd>, <Wn>, <cond> is equivalent to: - CSINC <Wd>, <Wn>, <Wn>, invert(<cond>). */ + CSINC <Wd>, <Wn>, <Wn>, invert(<cond>) + where <cond> is not AL or NV. */ static int convert_from_csel (aarch64_inst *inst) { - if (inst->operands[1].reg.regno == inst->operands[2].reg.regno) + if (inst->operands[1].reg.regno == inst->operands[2].reg.regno + && (inst->operands[3].cond->value & 0xe) != 0xe) { copy_operand_info (inst, 2, 3); inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond); @@ -1618,13 +1644,15 @@ convert_from_csel (aarch64_inst *inst) /* CSET <Wd>, <cond> is equivalent to: - CSINC <Wd>, WZR, WZR, invert(<cond>). */ + CSINC <Wd>, WZR, WZR, invert(<cond>) + where <cond> is not AL or NV. */ static int convert_csinc_to_cset (aarch64_inst *inst) { if (inst->operands[1].reg.regno == 0x1f - && inst->operands[2].reg.regno == 0x1f) + && inst->operands[2].reg.regno == 0x1f + && (inst->operands[3].cond->value & 0xe) != 0xe) { copy_operand_info (inst, 1, 3); inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond); |