aboutsummaryrefslogtreecommitdiff
path: root/opcodes/aarch64-opc.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2016-09-21 16:51:09 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2016-09-21 16:51:09 +0100
commit42408347b86745fdbd4bec9ee3a6a3fee31c4dee (patch)
tree5134e249ebca1ba93871174da6773e65965ae96d /opcodes/aarch64-opc.c
parent4989adac848eb8f2fee8b98d9615d2fded22623b (diff)
downloadgdb-42408347b86745fdbd4bec9ee3a6a3fee31c4dee.zip
gdb-42408347b86745fdbd4bec9ee3a6a3fee31c4dee.tar.gz
gdb-42408347b86745fdbd4bec9ee3a6a3fee31c4dee.tar.bz2
[AArch64][SVE 14/32] Make aarch64_logical_immediate_p take an element size
SVE supports logical immediate operations on 8-bit, 16-bit and 32-bit elements, treating them as aliases of operations on 64-bit elements in which the immediate is replicated. This patch therefore replaces the "32-bit/64-bit" input to aarch64_logical_immediate_p with a more general "number of bytes" input. opcodes/ * aarch64-opc.c (aarch64_logical_immediate_p): Replace is32 with an esize parameter. (operand_general_constraint_met_p): Update accordingly. Fix misindented code. * aarch64-asm.c (aarch64_ins_limm): Update call to aarch64_logical_immediate_p.
Diffstat (limited to 'opcodes/aarch64-opc.c')
-rw-r--r--opcodes/aarch64-opc.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index d870fd6..84da821 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1062,16 +1062,18 @@ build_immediate_table (void)
be accepted by logical (immediate) instructions
e.g. ORR <Xd|SP>, <Xn>, #<imm>.
- IS32 indicates whether or not VALUE is a 32-bit immediate.
+ ESIZE is the number of bytes in the decoded immediate value.
If ENCODING is not NULL, on the return of TRUE, the standard encoding for
VALUE will be returned in *ENCODING. */
bfd_boolean
-aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
+aarch64_logical_immediate_p (uint64_t value, int esize, aarch64_insn *encoding)
{
simd_imm_encoding imm_enc;
const simd_imm_encoding *imm_encoding;
static bfd_boolean initialized = FALSE;
+ uint64_t upper;
+ int i;
DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
value, is32);
@@ -1082,17 +1084,16 @@ aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
initialized = TRUE;
}
- if (is32)
- {
- /* Allow all zeros or all ones in top 32-bits, so that
- constant expressions like ~1 are permitted. */
- if (value >> 32 != 0 && value >> 32 != 0xffffffff)
- return FALSE;
+ /* Allow all zeros or all ones in top bits, so that
+ constant expressions like ~1 are permitted. */
+ upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
+ if ((value & ~upper) != value && (value | upper) != value)
+ return FALSE;
- /* Replicate the 32 lower bits to the 32 upper bits. */
- value &= 0xffffffff;
- value |= value << 32;
- }
+ /* Replicate to a full 64-bit value. */
+ value &= ~upper;
+ for (i = esize * 8; i < 64; i *= 2)
+ value |= (value << i);
imm_enc.imm = value;
imm_encoding = (const simd_imm_encoding *)
@@ -1645,7 +1646,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
case AARCH64_OPND_IMM_MOV:
{
- int is32 = aarch64_get_qualifier_esize (opnds[0].qualifier) == 4;
+ int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
imm = opnd->imm.value;
assert (idx == 1);
switch (opcode->op)
@@ -1654,7 +1655,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
imm = ~imm;
/* Fall through... */
case OP_MOV_IMM_WIDE:
- if (!aarch64_wide_constant_p (imm, is32, NULL))
+ if (!aarch64_wide_constant_p (imm, esize == 4, NULL))
{
set_other_error (mismatch_detail, idx,
_("immediate out of range"));
@@ -1662,7 +1663,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
}
break;
case OP_MOV_IMM_LOG:
- if (!aarch64_logical_immediate_p (imm, is32, NULL))
+ if (!aarch64_logical_immediate_p (imm, esize, NULL))
{
set_other_error (mismatch_detail, idx,
_("immediate out of range"));
@@ -1707,18 +1708,18 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
break;
case AARCH64_OPND_LIMM:
- {
- int is32 = opnds[0].qualifier == AARCH64_OPND_QLF_W;
- uint64_t uimm = opnd->imm.value;
- if (opcode->op == OP_BIC)
- uimm = ~uimm;
- if (aarch64_logical_immediate_p (uimm, is32, NULL) == FALSE)
- {
- set_other_error (mismatch_detail, idx,
- _("immediate out of range"));
- return 0;
- }
- }
+ {
+ int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
+ uint64_t uimm = opnd->imm.value;
+ if (opcode->op == OP_BIC)
+ uimm = ~uimm;
+ if (aarch64_logical_immediate_p (uimm, esize, NULL) == FALSE)
+ {
+ set_other_error (mismatch_detail, idx,
+ _("immediate out of range"));
+ return 0;
+ }
+ }
break;
case AARCH64_OPND_IMM0: