From 561a72d4ddf825ffaf8e88551e9bd6707cd6c59f Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Tue, 15 May 2018 16:11:42 +0100 Subject: Modify AArch64 Assembly and disassembly functions to be able to fail and report why. This patch if the first patch in a series to add the ability to add constraints to system registers that an instruction must adhere to in order for the register to be usable with that instruction. These constraints can also be used to disambiguate between registers with the same encoding during disassembly. This patch adds a new flags entry in the sysreg structures and ensures it is filled in and read out during assembly/disassembly. It also adds the ability for the assemble and disassemble functions to be able to gracefully fail and re-use the existing error reporting infrastructure. The return type of these functions are changed to a boolean to denote success or failure and the error structure is passed around to them. This requires aarch64-gen changes so a lot of the changes here are just mechanical. gas/ PR binutils/21446 * config/tc-aarch64.c (parse_sys_reg): Return register flags. (parse_operands): Fill in register flags. gdb/ PR binutils/21446 * aarch64-tdep.c (aarch64_analyze_prologue, aarch64_software_single_step, aarch64_displaced_step_copy_insn): Indicate not interested in errors. include/ PR binutils/21446 * opcode/aarch64.h (aarch64_opnd_info): Change sysreg to struct. (aarch64_decode_insn): Accept error struct. opcodes/ PR binutils/21446 * aarch64-asm.h (aarch64_insert_operand, aarch64_##x): Return boolean and take error struct. * aarch64-asm.c (aarch64_ext_regno, aarch64_ins_reglane, aarch64_ins_reglist, aarch64_ins_ldst_reglist, aarch64_ins_ldst_reglist_r, aarch64_ins_ldst_elemlist, aarch64_ins_advsimd_imm_shift, aarch64_ins_imm, aarch64_ins_imm_half, aarch64_ins_advsimd_imm_modified, aarch64_ins_fpimm, aarch64_ins_imm_rotate1, aarch64_ins_imm_rotate2, aarch64_ins_fbits, aarch64_ins_aimm, aarch64_ins_limm_1, aarch64_ins_limm, aarch64_ins_inv_limm, aarch64_ins_ft, aarch64_ins_addr_simple, aarch64_ins_addr_regoff, aarch64_ins_addr_offset, aarch64_ins_addr_simm, aarch64_ins_addr_simm10, aarch64_ins_addr_uimm12, aarch64_ins_simd_addr_post, aarch64_ins_cond, aarch64_ins_sysreg, aarch64_ins_pstatefield, aarch64_ins_sysins_op, aarch64_ins_barrier, aarch64_ins_prfop, aarch64_ins_hint, aarch64_ins_reg_extended, aarch64_ins_reg_shifted, aarch64_ins_sve_addr_ri_s4xvl, aarch64_ins_sve_addr_ri_s6xvl, aarch64_ins_sve_addr_ri_s9xvl, aarch64_ins_sve_addr_ri_s4, aarch64_ins_sve_addr_ri_u6, aarch64_ins_sve_addr_rr_lsl, aarch64_ins_sve_addr_rz_xtw, aarch64_ins_sve_addr_zi_u5, aarch64_ext_sve_addr_zz, aarch64_ins_sve_addr_zz_lsl, aarch64_ins_sve_addr_zz_sxtw, aarch64_ins_sve_addr_zz_uxtw, aarch64_ins_sve_aimm, aarch64_ins_sve_asimm, aarch64_ins_sve_index, aarch64_ins_sve_limm_mov, aarch64_ins_sve_quad_index, aarch64_ins_sve_reglist, aarch64_ins_sve_scale, aarch64_ins_sve_shlimm, aarch64_ins_sve_shrimm, aarch64_ins_sve_float_half_one, aarch64_ins_sve_float_half_two, aarch64_ins_sve_float_zero_one, aarch64_opcode_encode): Likewise. * aarch64-dis.h (aarch64_extract_operand, aarch64_##x): Likewise. * aarch64-dis.c (aarch64_ext_regno, aarch64_ext_reglane, aarch64_ext_reglist, aarch64_ext_ldst_reglist, aarch64_ext_ldst_reglist_r, aarch64_ext_ldst_elemlist, aarch64_ext_advsimd_imm_shift, aarch64_ext_imm, aarch64_ext_imm_half, aarch64_ext_advsimd_imm_modified, aarch64_ext_fpimm, aarch64_ext_imm_rotate1, aarch64_ext_imm_rotate2, aarch64_ext_fbits, aarch64_ext_aimm, aarch64_ext_limm_1, aarch64_ext_limm, decode_limm, aarch64_ext_inv_limm, aarch64_ext_ft, aarch64_ext_addr_simple, aarch64_ext_addr_regoff, aarch64_ext_addr_offset, aarch64_ext_addr_simm, aarch64_ext_addr_simm10, aarch64_ext_addr_uimm12, aarch64_ext_simd_addr_post, aarch64_ext_cond, aarch64_ext_sysreg, aarch64_ext_pstatefield, aarch64_ext_sysins_op, aarch64_ext_barrier, aarch64_ext_prfop, aarch64_ext_hint, aarch64_ext_reg_extended, aarch64_ext_reg_shifted, aarch64_ext_sve_addr_ri_s4xvl, aarch64_ext_sve_addr_ri_s6xvl, aarch64_ext_sve_addr_ri_s9xvl, aarch64_ext_sve_addr_ri_s4, aarch64_ext_sve_addr_ri_u6, aarch64_ext_sve_addr_rr_lsl, aarch64_ext_sve_addr_rz_xtw, aarch64_ext_sve_addr_zi_u5, aarch64_ext_sve_addr_zz, aarch64_ext_sve_addr_zz_lsl, aarch64_ext_sve_addr_zz_sxtw, aarch64_ext_sve_addr_zz_uxtw, aarch64_ext_sve_aimm, aarch64_ext_sve_asimm, aarch64_ext_sve_index, aarch64_ext_sve_limm_mov, aarch64_ext_sve_quad_index, aarch64_ext_sve_reglist, aarch64_ext_sve_scale, aarch64_ext_sve_shlimm, aarch64_ext_sve_shrimm, aarch64_ext_sve_float_half_one, aarch64_ext_sve_float_half_two, aarch64_ext_sve_float_zero_one, aarch64_opcode_decode): Likewise. (determine_disassembling_preference, aarch64_decode_insn, print_insn_aarch64_word, print_insn_data): Take errors struct. (print_insn_aarch64): Use errors. * aarch64-asm-2.c: Regenerate. * aarch64-dis-2.c: Regenerate. * aarch64-gen.c (print_operand_inserter): Use errors and change type to boolean in aarch64_insert_operan. (print_operand_extractor): Likewise. * aarch64-opc.c (aarch64_print_operand): Use sysreg struct. --- opcodes/aarch64-dis.c | 532 ++++++++++++++++++++++++++++---------------------- 1 file changed, 299 insertions(+), 233 deletions(-) (limited to 'opcodes/aarch64-dis.c') diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index e7bece9..5994b2b 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -242,31 +242,34 @@ get_expected_qualifier (const aarch64_inst *inst, int i) /* Operand extractors. */ -int +bfd_boolean aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { info->reg.regno = extract_field (self->fields[0], code, 0); - return 1; + return TRUE; } -int +bfd_boolean 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) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { assert (info->idx == 1 || info->idx ==3); info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1; - return 1; + return TRUE; } /* e.g. IC {, }. */ -int +bfd_boolean aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { info->reg.regno = extract_field (self->fields[0], code, 0); assert (info->idx == 1 @@ -277,14 +280,15 @@ aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info, not. */ info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op); - return 1; + return TRUE; } /* e.g. SQDMLAL , , .[]. */ -int +bfd_boolean aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { /* regno */ info->reglane.regno = extract_field (self->fields[0], code, @@ -320,7 +324,7 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, while (++pos <= 3 && (value & 0x1) == 0) value >>= 1; if (pos > 3) - return 0; + return FALSE; info->qualifier = get_sreg_qualifier_from_value (pos); info->reglane.index = (unsigned) (value >> 1); } @@ -337,7 +341,7 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, info->reglane.regno &= 0x1f; break; default: - return 0; + return FALSE; } } else if (inst->opcode->iclass == cryptosm3) @@ -369,38 +373,40 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info, info->reglane.index = extract_field (FLD_H, code, 0); break; default: - return 0; + return FALSE; } if (inst->opcode->op == OP_FCMLA_ELEM) { /* Complex operand takes two elements. */ if (info->reglane.index & 1) - return 0; + return FALSE; info->reglane.index /= 2; } } - return 1; + return TRUE; } -int +bfd_boolean aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { /* R */ info->reglist.first_regno = extract_field (self->fields[0], code, 0); /* len */ info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1; - return 1; + return TRUE; } /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */ -int +bfd_boolean aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst) + const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn value; /* Number of elements in each structure to be loaded/stored. */ @@ -431,20 +437,21 @@ aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED, value = extract_field (FLD_opcode, code, 0); /* PR 21595: Check for a bogus value. */ if (value >= ARRAY_SIZE (data)) - return 0; + return FALSE; if (expected_num != data[value].num_elements || data[value].is_reserved) - return 0; + return FALSE; info->reglist.num_regs = data[value].num_regs; - return 1; + return TRUE; } /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all lanes instructions. */ -int +bfd_boolean aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst) + const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn value; @@ -462,15 +469,16 @@ aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED, if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1) info->reglist.num_regs = 2; - return 1; + return TRUE; } /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD load/store single element instructions. */ -int +bfd_boolean aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_field field = {0, 0}; aarch64_insn QSsize; /* fields Q:S:size. */ @@ -493,7 +501,7 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, case 0x1: if (QSsize & 0x1) /* UND. */ - return 0; + return FALSE; info->qualifier = AARCH64_OPND_QLF_S_H; /* Index encoded in "Q:S:size<1>". */ info->reglist.index = QSsize >> 1; @@ -501,7 +509,7 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, case 0x2: if ((QSsize >> 1) & 0x1) /* UND. */ - return 0; + return FALSE; if ((QSsize & 0x1) == 0) { info->qualifier = AARCH64_OPND_QLF_S_S; @@ -512,14 +520,14 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, { if (extract_field (FLD_S, code, 0)) /* UND */ - return 0; + return FALSE; info->qualifier = AARCH64_OPND_QLF_S_D; /* Index encoded in "Q". */ info->reglist.index = QSsize >> 3; } break; default: - return 0; + return FALSE; } info->reglist.has_index = 1; @@ -529,17 +537,18 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, info->reglist.num_regs = get_opcode_dependent_value (inst->opcode); assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4); - return 1; + return TRUE; } /* Decode fields immh:immb and/or Q for e.g. SSHR ., ., # or SSHR , , #. */ -int +bfd_boolean aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst) + const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { int pos; aarch64_insn Q, imm, immh; @@ -547,7 +556,7 @@ aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED, immh = extract_field (FLD_immh, code, 0); if (immh == 0) - return 0; + return FALSE; imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb); pos = 4; /* Get highest set bit in immh. */ @@ -595,14 +604,15 @@ aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED, 1xxx (UInt(immh:immb)-64) */ info->imm.value = imm - (8 << pos); - return 1; + return TRUE; } /* Decode shift immediate for e.g. sshr (imm). */ -int +bfd_boolean aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { int64_t imm; aarch64_insn val; @@ -612,18 +622,19 @@ aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED, case 0: imm = 8; break; case 1: imm = 16; break; case 2: imm = 32; break; - default: return 0; + default: return FALSE; } info->imm.value = imm; - return 1; + return TRUE; } /* Decode imm for e.g. BFM , , #, #. value in the field(s) will be extracted as unsigned immediate value. */ -int +bfd_boolean aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { int64_t imm; @@ -639,28 +650,30 @@ aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info, imm <<= 12; info->imm.value = imm; - return 1; + return TRUE; } /* Decode imm and its shifter for e.g. MOVZ , #{, LSL #}. */ -int +bfd_boolean aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors) { - aarch64_ext_imm (self, info, code, inst); + aarch64_ext_imm (self, info, code, inst, errors); info->shifter.kind = AARCH64_MOD_LSL; info->shifter.amount = extract_field (FLD_hw, code, 0) << 4; - return 1; + return TRUE; } /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g. MOVI ., # {, LSL #}. */ -int +bfd_boolean aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { uint64_t imm; enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier; @@ -704,7 +717,7 @@ aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED, case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break; /* per word */ case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break; /* per half */ case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break; /* per byte */ - default: assert (0); return 0; + default: assert (0); return FALSE; } /* 00: 0; 01: 8; 10:16; 11:24. */ info->shifter.amount = extract_field_2 (&field, code, 0) << 3; @@ -717,63 +730,68 @@ aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED, break; default: assert (0); - return 0; + return FALSE; } - return 1; + return TRUE; } /* Decode an 8-bit floating-point immediate. */ -int +bfd_boolean aarch64_ext_fpimm (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { info->imm.value = extract_all_fields (self, code); info->imm.is_fp = 1; - return 1; + return TRUE; } /* Decode a 1-bit rotate immediate (#90 or #270). */ -int +bfd_boolean aarch64_ext_imm_rotate1 (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { uint64_t rot = extract_field (self->fields[0], code, 0); assert (rot < 2U); info->imm.value = rot * 180 + 90; - return 1; + return TRUE; } /* Decode a 2-bit rotate immediate (#0, #90, #180 or #270). */ -int +bfd_boolean aarch64_ext_imm_rotate2 (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { uint64_t rot = extract_field (self->fields[0], code, 0); assert (rot < 4U); info->imm.value = rot * 90; - return 1; + return TRUE; } /* Decode scale for e.g. SCVTF
, , #. */ -int +bfd_boolean aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { info->imm.value = 64- extract_field (FLD_scale, code, 0); - return 1; + return TRUE; } /* Decode arithmetic immediate for e.g. SUBS , , # {, }. */ -int +bfd_boolean aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn value; @@ -781,18 +799,18 @@ aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED, /* shift */ value = extract_field (FLD_shift, code, 0); if (value >= 2) - return 0; + return FALSE; info->shifter.amount = value ? 12 : 0; /* imm12 (unsigned) */ info->imm.value = extract_field (FLD_imm12, code, 0); - return 1; + return TRUE; } /* Return true if VALUE is a valid logical immediate encoding, storing the decoded value in *RESULT if so. ESIZE is the number of bytes in the decoded immediate. */ -static int +static bfd_boolean decode_limm (uint32_t esize, aarch64_insn value, int64_t *result) { uint64_t imm, mask; @@ -820,7 +838,7 @@ decode_limm (uint32_t esize, aarch64_insn value, int64_t *result) case 0x30 ... 0x37: /* 110xxx */ simd_size = 8; S &= 0x7; break; case 0x38 ... 0x3b: /* 1110xx */ simd_size = 4; S &= 0x3; break; case 0x3c ... 0x3d: /* 11110x */ simd_size = 2; S &= 0x1; break; - default: return 0; + default: return FALSE; } mask = (1ull << simd_size) - 1; /* Top bits are IGNORED. */ @@ -828,11 +846,11 @@ decode_limm (uint32_t esize, aarch64_insn value, int64_t *result) } if (simd_size > esize * 8) - return 0; + return FALSE; /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */ if (S == simd_size - 1) - return 0; + return FALSE; /* S+1 consecutive bits to 1. */ /* NOTE: S can't be 63 due to detection above. */ imm = (1ull << (S + 1)) - 1; @@ -858,14 +876,15 @@ decode_limm (uint32_t esize, aarch64_insn value, int64_t *result) *result = imm & ~((uint64_t) -1 << (esize * 4) << (esize * 4)); - return 1; + return TRUE; } /* Decode a logical immediate for e.g. ORR , , #. */ -int +bfd_boolean aarch64_ext_limm (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst) + const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { uint32_t esize; aarch64_insn value; @@ -877,23 +896,25 @@ aarch64_ext_limm (const aarch64_operand *self, } /* Decode a logical immediate for the BIC alias of AND (etc.). */ -int +bfd_boolean aarch64_ext_inv_limm (const aarch64_operand *self, aarch64_opnd_info *info, const aarch64_insn code, - const aarch64_inst *inst) + const aarch64_inst *inst, + aarch64_operand_error *errors) { - if (!aarch64_ext_limm (self, info, code, inst)) - return 0; + if (!aarch64_ext_limm (self, info, code, inst, errors)) + return FALSE; info->imm.value = ~info->imm.value; - return 1; + return TRUE; } /* Decode Ft for e.g. STR , [, {, {}}] or LDP , , [], #. */ -int +bfd_boolean aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, - const aarch64_insn code, const aarch64_inst *inst) + const aarch64_insn code, const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn value; @@ -913,7 +934,7 @@ aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED, case 0: qualifier = AARCH64_OPND_QLF_S_S; break; case 1: qualifier = AARCH64_OPND_QLF_S_D; break; case 2: qualifier = AARCH64_OPND_QLF_S_Q; break; - default: return 0; + default: return FALSE; } info->qualifier = qualifier; } @@ -922,31 +943,33 @@ aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED, /* opc1:size */ value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size); if (value > 0x4) - return 0; + return FALSE; info->qualifier = get_sreg_qualifier_from_value (value); } - return 1; + return TRUE; } /* Decode the address operand for e.g. STXRB , , [{,#0}]. */ -int +bfd_boolean aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { /* Rn */ info->addr.base_regno = extract_field (FLD_Rn, code, 0); - return 1; + return TRUE; } /* Decode the address operand for e.g. stlur , [{, }]. */ -int +bfd_boolean aarch64_ext_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, - aarch64_insn code, const aarch64_inst *inst) + aarch64_insn code, const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { info->qualifier = get_expected_qualifier (inst, info->idx); @@ -960,15 +983,16 @@ aarch64_ext_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED, info->addr.writeback = 1; info->addr.preind = 1; } - return 1; + return TRUE; } /* Decode the address operand for e.g. STR , [, {, {}}]. */ -int +bfd_boolean aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, - aarch64_insn code, const aarch64_inst *inst) + aarch64_insn code, const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn S, value; @@ -1004,13 +1028,14 @@ aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED, info->shifter.amount_present = 1; } - return 1; + return TRUE; } /* Decode the address operand for e.g. LDRSW , [], #. */ -int +bfd_boolean aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info, - aarch64_insn code, const aarch64_inst *inst) + aarch64_insn code, const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn imm; info->qualifier = get_expected_qualifier (inst, info->idx); @@ -1039,14 +1064,15 @@ aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info, info->addr.postind = 1; } - return 1; + return TRUE; } /* Decode the address operand for e.g. LDRSW , [{, #}]. */ -int +bfd_boolean aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info, aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { int shift; info->qualifier = get_expected_qualifier (inst, info->idx); @@ -1055,14 +1081,15 @@ aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info, info->addr.base_regno = extract_field (self->fields[0], code, 0); /* uimm12 */ info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift; - return 1; + return TRUE; } /* Decode the address operand for e.g. LDRAA , [{, #}]. */ -int +bfd_boolean aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info, aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn imm; @@ -1076,15 +1103,16 @@ aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info, info->addr.writeback = 1; info->addr.preind = 1; } - return 1; + return TRUE; } /* Decode the address operand for e.g. LD1 {., ., .}, [], >. */ -int +bfd_boolean aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, - aarch64_insn code, const aarch64_inst *inst) + aarch64_insn code, const aarch64_inst *inst, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { /* The opcode dependent area stores the number of elements in each structure to be loaded/stored. */ @@ -1110,57 +1138,61 @@ aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED, info->addr.offset.is_reg = 1; info->addr.writeback = 1; - return 1; + return TRUE; } /* Decode the condition operand for e.g. CSEL , , , . */ -int +bfd_boolean aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, - aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED) + aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { aarch64_insn value; /* cond */ value = extract_field (FLD_cond, code, 0); info->cond = get_cond_from_value (value); - return 1; + return TRUE; } /* Decode the system register operand for e.g. MRS , . */ -int +bfd_boolean aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { /* op0:op1:CRn:CRm:op2 */ - info->sysreg = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn, - FLD_CRm, FLD_op2); + info->sysreg.value = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn, + FLD_CRm, FLD_op2); return 1; } /* Decode the PSTATE field operand for e.g. MSR , #. */ -int +bfd_boolean aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { int i; /* op1:op2 */ info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2); for (i = 0; aarch64_pstatefields[i].name != NULL; ++i) if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield) - return 1; + return TRUE; /* Reserved value in . */ - return 0; + return FALSE; } /* Decode the system instruction op operand for e.g. AT , . */ -int +bfd_boolean aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info, aarch64_insn code, - const aarch64_inst *inst ATTRIBUTE_UNUSED) + const aarch64_inst *inst ATTRIBUTE_UNUSED, + aarch64_operand_error *errors ATTRIBUTE_UNUSED) { int i; aarch64_insn value; @@ -1176,7 +1208,7 @@ aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED, case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break; case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break; case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break; - default: assert (0); return 0; + default: assert (0); return FALSE; } for (i = 0; sysins_ops[i].name != NULL; ++i) @@ -1187,46 +1219,49 @@ aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED, info->sysins_op->name, (unsigned)info->sysins_op->value, aarch64_sys_ins_reg_has_xt (info->sysins_op), i); - return 1; + return TRUE; } - return 0; + return FALSE; } /* Decode the memory barrier option operand for e.g. DMB