default:
return 0;
}
+
+ if (inst->opcode->op == OP_FCMLA_ELEM)
+ {
+ /* Complex operand takes two elements. */
+ if (info->reglane.index & 1)
+ return 0;
+ info->reglane.index /= 2;
+ }
}
return 1;
return 1;
}
+/* Decode rotate immediate for FCMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #rotate. */
+int
+aarch64_ext_imm_rotate (const aarch64_operand *self, aarch64_opnd_info *info,
+ const aarch64_insn code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED)
+{
+ uint64_t rot = extract_field (self->fields[0], code, 0);
+
+ switch (info->type)
+ {
+ case AARCH64_OPND_IMM_ROT1:
+ case AARCH64_OPND_IMM_ROT2:
+ /* rot value
+ 0 0
+ 1 90
+ 2 180
+ 3 270 */
+ assert (rot < 4U);
+ break;
+ case AARCH64_OPND_IMM_ROT3:
+ /* rot value
+ 0 90
+ 1 270 */
+ assert (rot < 2U);
+ rot = 2 * rot + 1;
+ break;
+ default:
+ assert (0);
+ return 0;
+ }
+ info->imm.value = rot * 90;
+ return 1;
+}
+
/* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
int
aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
return 1;
}
+/* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}]. */
+int
+aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info,
+ aarch64_insn code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED)
+{
+ aarch64_insn imm;
+
+ info->qualifier = get_expected_qualifier (inst, info->idx);
+ /* Rn */
+ info->addr.base_regno = extract_field (self->fields[0], code, 0);
+ /* simm10 */
+ imm = extract_fields (code, 0, 2, self->fields[1], self->fields[2]);
+ info->addr.offset.imm = sign_extend (imm, 9) << 3;
+ if (extract_field (self->fields[3], code, 0) == 1) {
+ info->addr.writeback = 1;
+ info->addr.preind = 1;
+ }
+ return 1;
+}
+
/* Decode the address operand for e.g.
LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
int
aarch64_opnd_info *info, aarch64_insn code,
const aarch64_inst *inst ATTRIBUTE_UNUSED)
{
- int index;
+ int index_regno;
- index = extract_field (self->fields[1], code, 0);
- if (index == 31 && (self->flags & OPD_F_NO_ZR) != 0)
+ index_regno = extract_field (self->fields[1], code, 0);
+ if (index_regno == 31 && (self->flags & OPD_F_NO_ZR) != 0)
return 0;
info->addr.base_regno = extract_field (self->fields[0], code, 0);
- info->addr.offset.regno = index;
+ info->addr.offset.regno = index_regno;
info->addr.offset.is_reg = TRUE;
info->addr.writeback = FALSE;
info->addr.preind = TRUE;