X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc64%2Fxmon%2Fppc-dis.c;h=ac0a9d2427e060e62a4004614408161816b82a13;hb=918425d07b2fe2087ee7dabf90e69a17e914649c;hp=b614eb08deea1986bee12b3b7a43c1c6353e4093;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/arch/ppc64/xmon/ppc-dis.c b/arch/ppc64/xmon/ppc-dis.c index b614eb08d..ac0a9d242 100644 --- a/arch/ppc64/xmon/ppc-dis.c +++ b/arch/ppc64/xmon/ppc-dis.c @@ -22,37 +22,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #include "ansidecl.h" #include "ppc.h" -static int print_insn_powerpc PARAMS ((FILE *, unsigned long insn, - unsigned long memaddr, int dialect)); - -extern void print_address PARAMS((unsigned long memaddr)); - -/* Print a big endian PowerPC instruction. For convenience, also - disassemble instructions supported by the Motorola PowerPC 601. */ - -int -print_insn_big_powerpc (FILE *out, unsigned long insn, unsigned long memaddr) -{ - return print_insn_powerpc (out, insn, memaddr, - PPC_OPCODE_PPC | PPC_OPCODE_601); -} +extern void print_address (unsigned long memaddr); /* Print a PowerPC or POWER instruction. */ -static int -print_insn_powerpc (FILE *out, unsigned long insn, unsigned long memaddr, - int dialect) +int +print_insn_powerpc (unsigned long insn, unsigned long memaddr, int dialect) { const struct powerpc_opcode *opcode; const struct powerpc_opcode *opcode_end; unsigned long op; + if (dialect == 0) + dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON + | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC; + /* Get the major opcode of the instruction. */ op = PPC_OP (insn); /* Find the first match in the opcode table. We could speed this up a bit by doing a binary search on the major opcode. */ opcode_end = powerpc_opcodes + powerpc_num_opcodes; + again: for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++) { unsigned long table_op; @@ -64,109 +55,106 @@ print_insn_powerpc (FILE *out, unsigned long insn, unsigned long memaddr, table_op = PPC_OP (opcode->opcode); if (op < table_op) - break; + break; if (op > table_op) - continue; + continue; if ((insn & opcode->mask) != opcode->opcode || (opcode->flags & dialect) == 0) - continue; + continue; /* Make two passes over the operands. First see if any of them - have extraction functions, and, if they do, make sure the - instruction is valid. */ + have extraction functions, and, if they do, make sure the + instruction is valid. */ invalid = 0; for (opindex = opcode->operands; *opindex != 0; opindex++) - { - operand = powerpc_operands + *opindex; - if (operand->extract) - (*operand->extract) (insn, &invalid); - } + { + operand = powerpc_operands + *opindex; + if (operand->extract) + (*operand->extract) (insn, dialect, &invalid); + } if (invalid) - continue; + continue; /* The instruction is valid. */ - fprintf(out, "%s", opcode->name); + printf("%s", opcode->name); if (opcode->operands[0] != 0) - fprintf(out, "\t"); + printf("\t"); /* Now extract and print the operands. */ need_comma = 0; need_paren = 0; for (opindex = opcode->operands; *opindex != 0; opindex++) + { + long value; + + operand = powerpc_operands + *opindex; + + /* Operands that are marked FAKE are simply ignored. We + already made sure that the extract function considered + the instruction to be valid. */ + 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) & ((1 << operand->bits) - 1); + if ((operand->flags & PPC_OPERAND_SIGNED) != 0 + && (value & (1 << (operand->bits - 1))) != 0) + value -= 1 << operand->bits; + } + + /* 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) + continue; + + if (need_comma) + { + printf(","); + need_comma = 0; + } + + /* Print the operand as directed by the flags. */ + if ((operand->flags & PPC_OPERAND_GPR) != 0) + printf("r%ld", value); + else if ((operand->flags & PPC_OPERAND_FPR) != 0) + printf("f%ld", value); + else if ((operand->flags & PPC_OPERAND_VR) != 0) + printf("v%ld", value); + else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) + print_address (memaddr + value); + else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) + print_address (value & 0xffffffff); + else if ((operand->flags & PPC_OPERAND_CR) == 0 + || (dialect & PPC_OPCODE_PPC) == 0) + printf("%ld", value); + else + { + if (operand->bits == 3) + printf("cr%d", value); + else { - long value; - - operand = powerpc_operands + *opindex; - - /* Operands that are marked FAKE are simply ignored. We - already made sure that the extract function considered - the instruction to be valid. */ - if ((operand->flags & PPC_OPERAND_FAKE) != 0) - continue; - - /* Extract the value from the instruction. */ - if (operand->extract) - value = (*operand->extract) (insn, (int *) 0); - else - { - value = (insn >> operand->shift) & ((1 << operand->bits) - 1); - if ((operand->flags & PPC_OPERAND_SIGNED) != 0 - && (value & (1 << (operand->bits - 1))) != 0) - value -= 1 << operand->bits; - } - - /* 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) - continue; - - if (need_comma) - { - fprintf(out, ","); - need_comma = 0; - } - - /* Print the operand as directed by the flags. */ - if ((operand->flags & PPC_OPERAND_GPR) != 0) - fprintf(out, "r%ld", value); - else if ((operand->flags & PPC_OPERAND_FPR) != 0) - fprintf(out, "f%ld", value); - else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) - print_address (memaddr + value); - else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) - print_address (value & 0xffffffff); - else if ((operand->flags & PPC_OPERAND_CR) == 0 - || (dialect & PPC_OPCODE_PPC) == 0) - fprintf(out, "%ld", value); - else - { - if (operand->bits == 3) - fprintf(out, "cr%d", value); - else - { - static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; - int cr; - int cc; - - cr = value >> 2; - if (cr != 0) - fprintf(out, "4*cr%d", cr); - cc = value & 3; - if (cc != 0) - { - if (cr != 0) - fprintf(out, "+"); - fprintf(out, "%s", cbnames[cc]); - } - } + static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; + int cr; + int cc; + + cr = value >> 2; + if (cr != 0) + printf("4*cr%d+", cr); + cc = value & 3; + printf("%s", cbnames[cc]); + } } if (need_paren) { - fprintf(out, ")"); + printf(")"); need_paren = 0; } @@ -174,7 +162,7 @@ print_insn_powerpc (FILE *out, unsigned long insn, unsigned long memaddr, need_comma = 1; else { - fprintf(out, "("); + printf("("); need_paren = 1; } } @@ -183,8 +171,14 @@ print_insn_powerpc (FILE *out, unsigned long insn, unsigned long memaddr, return 4; } + if ((dialect & PPC_OPCODE_ANY) != 0) + { + dialect = ~PPC_OPCODE_ANY; + goto again; + } + /* We could not find a match. */ - fprintf(out, ".long 0x%lx", insn); + printf(".long 0x%lx", insn); return 4; }