diff options
author | Ken Raeburn <raeburn@cygnus> | 1993-06-11 23:20:54 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1993-06-11 23:20:54 +0000 |
commit | 112087edcc267e1f0db9a1286520959dac5e2081 (patch) | |
tree | d11082ecd34dd2b146fb05900117b361bef796fa /gdb/hppa-pinsn.c | |
parent | 57cb418a935f699a59f534e9d92223a9f1792f9d (diff) | |
download | gdb-112087edcc267e1f0db9a1286520959dac5e2081.zip gdb-112087edcc267e1f0db9a1286520959dac5e2081.tar.gz gdb-112087edcc267e1f0db9a1286520959dac5e2081.tar.bz2 |
Lots of changes from Jeff Law for HPPA support:
Clean up cruft in opcode table; improve opcodes library disassembler; make
gdb use opcodes library disassembler.
Diffstat (limited to 'gdb/hppa-pinsn.c')
-rw-r--r-- | gdb/hppa-pinsn.c | 432 |
1 files changed, 6 insertions, 426 deletions
diff --git a/gdb/hppa-pinsn.c b/gdb/hppa-pinsn.c index a22b3d6..00b6e47 100644 --- a/gdb/hppa-pinsn.c +++ b/gdb/hppa-pinsn.c @@ -21,438 +21,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" -#include "symtab.h" -#define OLD_TABLE -#include "opcode/hppa.h" +#include "dis-asm.h" -static char *control_reg[] = -{ "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", - "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4", - "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr", - "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3", - "tr4", "tr5", "tr6", "tr7" - }; - -static char *compare_cond_names[] = -{ "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", - ",od", ",tr", ",<>", ",>=", ",>", ",>>=", - ",>>", ",nsv", ",ev" - }; - -static char *add_cond_names[] = -{ "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", - ",od", ",tr", ",<>", ",>=", ",>", ",uv", - ",vnz", ",nsv", ",ev" - }; - -static char *logical_cond_names[] = -{ "", ",=", ",<", ",<=", 0, 0, 0, ",od", - ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev" - }; - -static char *unit_cond_names[] = -{ "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc", - ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc" - }; - -static char *shift_cond_names[] = -{"", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"}; - -static char *index_compl_names[] = {"", ",m", ",s", ",sm"}; -static char *short_ldst_compl_names[] = {"", ",ma", "", ",mb"}; -static char *short_bytes_compl_names[] = {"", ",b,m", ",e", ",e,m"}; -static char *float_format_names[] = {",sgl", ",dbl", ",quad"}; -static char *float_comp_names[] = -{",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>", - ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>", - ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<", - ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true" - }; - -/* For a bunch of different instructions form an index into a - completer name table. */ -#define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \ - GET_FIELD (insn, 18, 18) << 1) - -#define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \ - (GET_FIELD ((insn), 19, 19) ? 8 : 0)) - -static void fput_reg PARAMS ((unsigned reg, FILE *stream)); -static void fput_const PARAMS ((unsigned num, FILE *stream)); -static void fput_reg_r PARAMS ((unsigned reg, FILE *stream)); -static void fput_creg PARAMS ((unsigned reg, FILE *stream)); - -/* Print one instruction from MEMADDR on STREAM. */ +/* Print the instruction at address MEMADDR in debugged memory, + on STREAM. Returns length of the instruction, in bytes. */ int print_insn (memaddr, stream) CORE_ADDR memaddr; FILE *stream; { - long insn; - unsigned int i, op; - - insn = read_memory_integer (memaddr, sizeof (insn)); - - for (i = 0; i < NUMOPCODES; ++i) - { - const struct pa_opcode *opcode = &pa_opcodes[i]; - if ((insn & opcode->mask) == opcode->match) - { - register const char *s; - - fputs_filtered (opcode->name, stream); - - if (!index ("cCY<?!@-+&U>~nZFIM", opcode->args[0])) - fputs_filtered (" ", stream); - for (s = opcode->args; *s != '\0'; ++s) - { - switch (*s) - { - case 'x': - fput_reg (GET_FIELD (insn, 11, 15), stream); - break; - case 'X': - if (GET_FIELD (insn, 25, 25)) - fput_reg_r (GET_FIELD (insn, 11, 15), stream); - else - fput_reg (GET_FIELD (insn, 11, 15), stream); - break; - case 'b': - fput_reg (GET_FIELD (insn, 6, 10), stream); - break; - case '^': - fput_creg (GET_FIELD (insn, 6, 10), stream); - break; - case 'E': - if (GET_FIELD (insn, 25, 25)) - fput_reg_r (GET_FIELD (insn, 6, 10), stream); - else - fput_reg (GET_FIELD (insn, 6, 10), stream); - break; - case 't': - fput_reg (GET_FIELD (insn, 27, 31), stream); - break; - case 'v': - if (GET_FIELD (insn, 25, 25)) - fput_reg_r (GET_FIELD (insn, 27, 31), stream); - else - fput_reg (GET_FIELD (insn, 27, 31), stream); - break; - case '4': - fput_creg (GET_FIELD (insn, 6, 10), stream); - break; - case '6': - fput_reg (GET_FIELD (insn, 11, 15), stream); - break; - case '7': - fput_reg (GET_FIELD (insn, 27, 31), stream); - break; - case '8': - fput_reg (GET_FIELD (insn, 16, 20), stream); - break; - case '9': - fput_reg (GET_FIELD (insn, 21, 25), stream); - break; - case '5': - fput_const (extract_5_load (insn), stream); - break; - /* case 's': */ - case 'S': - fprintf_filtered (stream, "sr%d", extract_3 (insn)); - break; - case 'c': - fprintf_filtered (stream, "%s ", - index_compl_names[GET_COMPL (insn)]); - break; - case 'C': - fprintf_filtered (stream, "%s ", - short_ldst_compl_names[GET_COMPL (insn)]); - break; - case 'Y': - fprintf_filtered (stream, "%s ", - short_bytes_compl_names[GET_COMPL (insn)]); - break; - /* these four conditions are for the set of instructions - which distinguish true/false conditions by opcode rather - than by the 'f' bit (sigh): comb, comib, addb, addib */ - case '<': - fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)], - stream); - break; - case '?': - fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18) + 8], - stream); - break; - case '!': - fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)], - stream); - break; - case '@': - fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18) + 8], - stream); - break; - case '-': - fprintf_filtered (stream, "%s ", - compare_cond_names[GET_COND (insn)]); - break; - case '+': - fprintf_filtered (stream, "%s ", - add_cond_names[GET_FIELD (insn, 16, 18)]); - break; - - case '&': - fprintf_filtered (stream, "%s ", - logical_cond_names[GET_COND (insn)]); - break; - case 'U': - fprintf_filtered (stream, "%s ", - unit_cond_names[GET_COND (insn)]); - break; - case '>': - case '~': - fprintf_filtered (stream, "%s ", - shift_cond_names[GET_FIELD (insn, 16, 18)]); - break; - case 'V': - fput_const (extract_5_store (insn), stream); - break; - case 'r': - fput_const (extract_5r_store (insn), stream); - break; - case 'R': - fput_const (extract_5R_store (insn), stream); - break; - case 'i': - fput_const (extract_11 (insn), stream); - break; - case 'j': - fput_const (extract_14 (insn), stream); - break; - case 'k': - fput_const (extract_21 (insn), stream); - break; - case 'n': - if (insn & 0x2) - fprintf_filtered (stream, ",n "); - else - fprintf_filtered (stream, " "); - break; - case 'w': - print_address (memaddr + 8 + extract_12 (insn), stream); - break; - case 'W': - op = GET_FIELD (insn, 0, 5); - - if (op == 0x38 /* be */ || op == 0x39 /* ble */) - fput_const (extract_17 (insn), stream); - else - print_address (memaddr + 8 + extract_17 (insn), stream); - - break; - case 'B': - { - int space; - if (space = GET_FIELD (insn, 16, 17)) - fprintf_filtered (stream, "sr%d,", space); - fput_reg (GET_FIELD (insn, 6, 10), stream); - break; - } - case 'p': - fprintf_filtered (stream, "%d", - 31 - GET_FIELD (insn, 22, 26)); - break; - case 'P': - fprintf_filtered (stream, "%d", - GET_FIELD (insn, 22, 26)); - break; - case 'Q': - fprintf_filtered (stream, "%d", - GET_FIELD (insn, 11, 15)); - break; - case 'T': - fprintf_filtered (stream, "%d", - 32 - GET_FIELD (insn, 27, 31)); - break; - case 'A': - fput_const (GET_FIELD (insn, 6, 18), stream); - break; - case 'Z': - if (GET_FIELD (insn, 26, 26)) - fprintf_filtered (stream, ",m "); - else - fprintf_filtered (stream, " "); - break; - case 'D': - fput_const (GET_FIELD (insn, 6, 31), stream); - break; - case 'f': - fprintf_filtered (stream, ",%d", GET_FIELD (insn, 23, 25)); - break; - case 'O': - fput_const ((GET_FIELD (insn, 6,20) << 5 | - GET_FIELD (insn, 27, 31)), stream); - break; - case 'o': - fput_const (GET_FIELD (insn, 6, 20), stream); - break; - case '2': - fput_const ((GET_FIELD (insn, 6, 22) << 5 | - GET_FIELD (insn, 27, 31)), stream); - break; - case '1': - fput_const ((GET_FIELD (insn, 11, 20) << 5 | - GET_FIELD (insn, 27, 31)), stream); - break; - case '0': - fput_const ((GET_FIELD (insn, 16, 20) << 5 | - GET_FIELD (insn, 27, 31)), stream); - break; - case 'u': - fprintf_filtered (stream, "%d", GET_FIELD (insn, 23, 25)); - break; - case 'F': - /* if no destination completer, need a space here */ - if (GET_FIELD (insn, 21, 22) == 1) - fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)], - stream); - else - fprintf_filtered (stream, "%s ", - float_format_names[GET_FIELD - (insn, 19, 20)]); - break; - case 'G': - fprintf_filtered (stream, "%s ", - float_format_names[GET_FIELD (insn, - 17, 18)]); - break; - case 'H': - fputs_filtered (float_format_names[GET_FIELD - (insn, 26, 26)], stream); - break; - case 'I': - /* if no destination completer, need a space here */ - if (GET_FIELD (insn, 21, 22) == 1) - fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)], - stream); - else - fprintf_filtered (stream, "%s ", - float_format_names[GET_FIELD - (insn, 20, 20)]); - break; - case 'J': - if (GET_FIELD (insn, 24, 24)) - fput_reg_r (GET_FIELD (insn, 6, 10), stream); - else - fput_reg (GET_FIELD (insn, 6, 10), stream); - - break; - case 'K': - if (GET_FIELD (insn, 19, 19)) - fput_reg_r (GET_FIELD (insn, 11, 15), stream); - else - fput_reg (GET_FIELD (insn, 11, 15), stream); - break; - case 'M': - fputs_filtered (float_comp_names[GET_FIELD (insn, 27, 31)], - stream); - break; - case '}': - fprintf_filtered (stream, "fp%d", GET_FIELD (insn, 6, 10)); - break; - case '|': - fprintf_filtered (stream, "fp%d", GET_FIELD (insn, 11, 15)); - break; - case '{': - if (GET_FIELD (insn, 23, 25) == 0) - fprintf_filtered (stream, "fp%d", - GET_FIELD (insn, 27, 31)); - else - fprintf_filtered (stream, "cp%d", - GET_FIELD (insn, 27, 31)); - break; - default: - fprintf_filtered (stream, "%c", *s); - break; - } - } - -/* If this is an external branch, examine the previous instruction and see if - it was an ldil that loaded something into the same base reg. If so, then - calculate the branch target from the constants in both instructions, and - print it out. */ - - op = GET_FIELD (insn, 0, 5); - if (op == 0x38 /* be */ || op == 0x39 /* ble */) - { - CORE_ADDR target_address; - long prev_insn; - int basereg, basereg_prev; - - target_address = extract_17 (insn); - basereg = GET_FIELD (insn, 6, 10); - if (basereg != 0) - { - prev_insn = read_memory_integer (memaddr - 4, - sizeof(prev_insn)); - basereg_prev = GET_FIELD (prev_insn, 6, 10); + disassemble_info info; - if ((prev_insn & 0xfc000000) == 0x20000000 /* ldil */ - && basereg == basereg_prev) - target_address += extract_21 (prev_insn); - } - fprintf_filtered (stream, "\t! "); - print_address (target_address, stream); - } + GDB_INIT_DISASSEMBLE_INFO (info, stream); - return sizeof(insn); - } - } - fprintf_filtered (stream, "%#8x", insn); - return sizeof(insn); -} - -/* Utility function to print registers */ - -static void -fput_reg (reg, stream) - unsigned reg; - FILE *stream; -{ - if (reg) - fputs_filtered (reg_names[reg], stream); - else - fputs_filtered ("r0", stream); -} - -void -fput_reg_r (reg, stream) - unsigned reg; - FILE *stream; -{ - if (reg) - fputs_filtered (reg_names[reg], stream); - else - fputs_filtered ("r0", stream); - fputs_filtered ("R", stream); -} - -void -fput_creg (reg, stream) - unsigned reg; - FILE *stream; -{ - fputs_filtered (control_reg[reg], stream); -} - -/* print constants with sign */ - -void -fput_const (num, stream) - unsigned num; - FILE *stream; -{ - if ((int)num < 0) - fprintf_filtered (stream, "-%x", -(int)num); - else - fprintf_filtered (stream, "%x", num); + return print_insn_hppa (memaddr, &info); } |