diff options
Diffstat (limited to 'gas/config/tc-ppc.c')
-rw-r--r-- | gas/config/tc-ppc.c | 37 |
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) |