* ppc-dis.c (operand_value_powerpc, skip_optional_operands): New.
(print_insn_powerpc): Use the new operand_value_powerpc and skip_optional_operands functions to omit or print all optional operands as a group. * ppc-opc.c (BFF, W, XFL_L, XWRA_MASK): New. (XFL_MASK): Delete L and W bits from the mask. (mtfsfi, mtfsfi.): Replace use of BF with BFF. Relpace use of XRA_MASK with XWRA_MASK. Use W. (mtfsf, mtfsf.): Use XFL_L and W.
This commit is contained in:
parent
f891f2a91d
commit
ea192fa395
@ -1,3 +1,15 @@
|
||||
2007-05-16 Peter Bergner <bergner@vnet.ibm.com>
|
||||
|
||||
* ppc-dis.c (operand_value_powerpc, skip_optional_operands): New.
|
||||
(print_insn_powerpc): Use the new operand_value_powerpc and
|
||||
skip_optional_operands functions to omit or print all optional
|
||||
operands as a group.
|
||||
* ppc-opc.c (BFF, W, XFL_L, XWRA_MASK): New.
|
||||
(XFL_MASK): Delete L and W bits from the mask.
|
||||
(mtfsfi, mtfsfi.): Replace use of BF with BFF. Relpace use of XRA_MASK
|
||||
with XWRA_MASK. Use W.
|
||||
(mtfsf, mtfsf.): Use XFL_L and W.
|
||||
|
||||
2007-05-14 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR binutils/4502
|
||||
|
@ -127,6 +127,56 @@ print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
|
||||
return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
|
||||
}
|
||||
|
||||
/* Extract the operand value from the PowerPC or POWER instruction. */
|
||||
|
||||
static long
|
||||
operand_value_powerpc (const struct powerpc_operand *operand,
|
||||
unsigned long insn, int dialect)
|
||||
{
|
||||
long value;
|
||||
int invalid;
|
||||
/* Extract the value from the instruction. */
|
||||
if (operand->extract)
|
||||
value = (*operand->extract) (insn, dialect, &invalid);
|
||||
else
|
||||
{
|
||||
value = (insn >> operand->shift) & operand->bitm;
|
||||
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
||||
{
|
||||
/* BITM is always some number of zeros followed by some
|
||||
number of ones, followed by some numer of zeros. */
|
||||
unsigned long top = operand->bitm;
|
||||
/* top & -top gives the rightmost 1 bit, so this
|
||||
fills in any trailing zeros. */
|
||||
top |= (top & -top) - 1;
|
||||
top &= ~(top >> 1);
|
||||
value = (value ^ top) - top;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Determine whether the optional operand(s) should be printed. */
|
||||
|
||||
static int
|
||||
skip_optional_operands (const unsigned char *opindex,
|
||||
unsigned long insn, int dialect)
|
||||
{
|
||||
const struct powerpc_operand *operand;
|
||||
|
||||
for (; *opindex != 0; opindex++)
|
||||
{
|
||||
operand = &powerpc_operands[*opindex];
|
||||
if ((operand->flags & PPC_OPERAND_NEXT) != 0
|
||||
|| ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
|
||||
&& operand_value_powerpc (operand, insn, dialect) != 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print a PowerPC or POWER instruction. */
|
||||
|
||||
static int
|
||||
@ -172,6 +222,7 @@ print_insn_powerpc (bfd_vma memaddr,
|
||||
int invalid;
|
||||
int need_comma;
|
||||
int need_paren;
|
||||
int skip_optional;
|
||||
|
||||
table_op = PPC_OP (opcode->opcode);
|
||||
if (op < table_op)
|
||||
@ -205,6 +256,7 @@ print_insn_powerpc (bfd_vma memaddr,
|
||||
/* Now extract and print the operands. */
|
||||
need_comma = 0;
|
||||
need_paren = 0;
|
||||
skip_optional = -1;
|
||||
for (opindex = opcode->operands; *opindex != 0; opindex++)
|
||||
{
|
||||
long value;
|
||||
@ -217,32 +269,17 @@ print_insn_powerpc (bfd_vma memaddr,
|
||||
if ((operand->flags & PPC_OPERAND_FAKE) != 0)
|
||||
continue;
|
||||
|
||||
/* Extract the value from the instruction. */
|
||||
if (operand->extract)
|
||||
value = (*operand->extract) (insn, dialect, &invalid);
|
||||
else
|
||||
{
|
||||
value = (insn >> operand->shift) & operand->bitm;
|
||||
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
|
||||
{
|
||||
/* BITM is always some number of zeros followed by some
|
||||
number of ones, followed by some numer of zeros. */
|
||||
unsigned long top = operand->bitm;
|
||||
/* top & -top gives the rightmost 1 bit, so this
|
||||
fills in any trailing zeros. */
|
||||
top |= (top & -top) - 1;
|
||||
top &= ~(top >> 1);
|
||||
value = (value ^ top) - top;
|
||||
}
|
||||
}
|
||||
/* If all of the optional operands have the value zero,
|
||||
then don't print any of them. */
|
||||
if (skip_optional < 0
|
||||
&& (operand->flags & PPC_OPERAND_OPTIONAL) != 0)
|
||||
skip_optional = skip_optional_operands (opindex, insn, dialect);
|
||||
|
||||
/* If the operand is optional, and the value is zero, don't
|
||||
print anything. */
|
||||
if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
|
||||
&& (operand->flags & PPC_OPERAND_NEXT) == 0
|
||||
&& value == 0)
|
||||
if (skip_optional > 0)
|
||||
continue;
|
||||
|
||||
value = operand_value_powerpc (operand, insn, dialect);
|
||||
|
||||
if (need_comma)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, ",");
|
||||
|
@ -154,9 +154,13 @@ const struct powerpc_operand powerpc_operands[] =
|
||||
#define CRFD BF
|
||||
{ 0x7, 23, NULL, NULL, PPC_OPERAND_CR },
|
||||
|
||||
/* The BF field in an X or XL form instruction. */
|
||||
#define BFF BF + 1
|
||||
{ 0x7, 23, NULL, NULL, 0 },
|
||||
|
||||
/* An optional BF field. This is used for comparison instructions,
|
||||
in which an omitted BF field is taken as zero. */
|
||||
#define OBF BF + 1
|
||||
#define OBF BFF + 1
|
||||
{ 0x7, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
|
||||
|
||||
/* The BFA field in an X or XL form instruction. */
|
||||
@ -515,8 +519,9 @@ const struct powerpc_operand powerpc_operands[] =
|
||||
#define WS EVUIMM_8 + 1
|
||||
{ 0x7, 11, NULL, NULL, 0 },
|
||||
|
||||
/* The L field in an mtmsrd or A form instruction. */
|
||||
/* The L field in an mtmsrd or A form instruction or W in an X form. */
|
||||
#define A_L WS + 1
|
||||
#define W A_L
|
||||
{ 0x1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL },
|
||||
|
||||
#define RMC A_L + 1
|
||||
@ -541,6 +546,10 @@ const struct powerpc_operand powerpc_operands[] =
|
||||
/* The EH field in larx instruction. */
|
||||
#define EH SH16 + 1
|
||||
{ 0x1, 0, NULL, NULL, PPC_OPERAND_OPTIONAL },
|
||||
|
||||
/* The L field in an mtfsf or XFL form instruction. */
|
||||
#define XFL_L EH + 1
|
||||
{ 0x1, 25, NULL, NULL, PPC_OPERAND_OPTIONAL},
|
||||
};
|
||||
|
||||
const unsigned int num_powerpc_operands = (sizeof (powerpc_operands)
|
||||
@ -1400,6 +1409,9 @@ extract_tbr (unsigned long insn,
|
||||
/* An X_MASK with the RA field fixed. */
|
||||
#define XRA_MASK (X_MASK | RA_MASK)
|
||||
|
||||
/* An XRA_MASK with the W field clear. */
|
||||
#define XWRA_MASK (XRA_MASK & ~((unsigned long) 1 << 16))
|
||||
|
||||
/* An X_MASK with the RB field fixed. */
|
||||
#define XRB_MASK (X_MASK | RB_MASK)
|
||||
|
||||
@ -1454,7 +1466,7 @@ extract_tbr (unsigned long insn,
|
||||
|
||||
/* An XFL form instruction. */
|
||||
#define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1))
|
||||
#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (((unsigned long)1) << 25) | (((unsigned long)1) << 16))
|
||||
#define XFL_MASK XFL (0x3f, 0x3ff, 1)
|
||||
|
||||
/* An X form isel instruction. */
|
||||
#define XISEL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1))
|
||||
@ -4586,8 +4598,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
|
||||
|
||||
{ "dcmpoq", X(63,130), X_MASK, POWER6, { BF, FRA, FRB } },
|
||||
|
||||
{ "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
|
||||
{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
|
||||
{ "mtfsfi", XRC(63,134,0), XWRA_MASK|(3<<21)|(1<<11), COM, { BFF, U, W } },
|
||||
{ "mtfsfi.", XRC(63,134,1), XWRA_MASK|(3<<21)|(1<<11), COM, { BFF, U, W } },
|
||||
|
||||
{ "fnabs", XRC(63,136,0), XRA_MASK, COM, { FRT, FRB } },
|
||||
{ "fnabs.", XRC(63,136,1), XRA_MASK, COM, { FRT, FRB } },
|
||||
@ -4636,8 +4648,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
|
||||
|
||||
{ "dtstsfq", X(63,674), X_MASK, POWER6, { BF, FRA, FRB } },
|
||||
|
||||
{ "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB } },
|
||||
{ "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB } },
|
||||
{ "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB, XFL_L, W } },
|
||||
{ "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB, XFL_L, W } },
|
||||
|
||||
{ "drdpq", XRC(63,770,0), X_MASK, POWER6, { FRT, FRB } },
|
||||
{ "drdpq.", XRC(63,770,1), X_MASK, POWER6, { FRT, FRB } },
|
||||
|
Loading…
Reference in New Issue
Block a user