aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-ppc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/config/tc-ppc.c')
-rw-r--r--gas/config/tc-ppc.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 694c47a..9a06668 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -1522,23 +1522,32 @@ insn_validate (const struct powerpc_opcode *op)
}
else
{
+ uint64_t mask;
const struct powerpc_operand *operand = &powerpc_operands[*o];
- if (operand->shift != (int) PPC_OPSHIFT_INV)
+ if (operand->shift == (int) PPC_OPSHIFT_INV)
{
- uint64_t mask;
-
- if (operand->shift >= 0)
- mask = operand->bitm << operand->shift;
- else
- mask = operand->bitm >> -operand->shift;
- if (omask & mask)
- {
- as_bad (_("operand %d overlap in %s"),
- (int) (o - op->operands), op->name);
- return TRUE;
- }
- omask |= mask;
+ const char *errmsg;
+ int64_t val;
+
+ errmsg = NULL;
+ val = -1;
+ if ((operand->flags & PPC_OPERAND_NEGATIVE) != 0)
+ val = -val;
+ else if ((operand->flags & PPC_OPERAND_PLUS1) != 0)
+ val += 1;
+ mask = (*operand->insert) (0, val, ppc_cpu, &errmsg);
+ }
+ else if (operand->shift >= 0)
+ mask = operand->bitm << operand->shift;
+ else
+ mask = operand->bitm >> -operand->shift;
+ if (omask & mask)
+ {
+ as_bad (_("operand %d overlap in %s"),
+ (int) (o - op->operands), op->name);
+ return TRUE;
}
+ omask |= mask;
if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
optional = TRUE;
else if (optional)