X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=opcodes%2Ftic4x-dis.c;h=a99b52a7ad01a329bc2cdc329d261ab4a9ec372c;hb=5aae9ae97f65f6651cf91db856a1f8b4bef5e896;hp=92c9dcb4cb36145ed7ed3708cfa89e8d332ce7ce;hpb=1a0670f37442b7ae904932b347353046126b990c;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/tic4x-dis.c b/opcodes/tic4x-dis.c index 92c9dcb4cb..a99b52a7ad 100644 --- a/opcodes/tic4x-dis.c +++ b/opcodes/tic4x-dis.c @@ -1,6 +1,6 @@ /* Print instructions for the Texas TMS320C[34]X, for GDB and GNU Binutils. - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2020 Free Software Foundation, Inc. Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz) @@ -24,7 +24,7 @@ #include "sysdep.h" #include #include "libiberty.h" -#include "dis-asm.h" +#include "disassemble.h" #include "opcode/tic4x.h" #define TIC4X_DEBUG 0 @@ -51,8 +51,11 @@ typedef enum } indirect_t; -static int tic4x_version = 0; -static int tic4x_dp = 0; +static unsigned long tic4x_version = 0; +static unsigned int tic4x_dp = 0; +static tic4x_inst_t **optab = NULL; +static tic4x_inst_t **optab_special = NULL; +static const char *registernames[REG_TABLE_SIZE]; static int tic4x_pc_offset (unsigned int op) @@ -130,27 +133,24 @@ tic4x_print_str (struct disassemble_info *info, const char *str) static int tic4x_print_register (struct disassemble_info *info, unsigned long regno) { - static tic4x_register_t ** registertable = NULL; unsigned int i; - if (registertable == NULL) + if (registernames[REG_R0] == NULL) { - registertable = xmalloc (sizeof (tic4x_register_t *) * REG_TABLE_SIZE); for (i = 0; i < tic3x_num_registers; i++) - registertable[tic3x_registers[i].regno] = (tic4x_register_t *) (tic3x_registers + i); + registernames[tic3x_registers[i].regno] = tic3x_registers[i].name; if (IS_CPU_TIC4X (tic4x_version)) { /* Add C4x additional registers, overwriting any C3x registers if necessary. */ for (i = 0; i < tic4x_num_registers; i++) - registertable[tic4x_registers[i].regno] = - (tic4x_register_t *)(tic4x_registers + i); + registernames[tic4x_registers[i].regno] = tic4x_registers[i].name; } } - if ((int) regno > (IS_CPU_TIC4X (tic4x_version) ? TIC4X_REG_MAX : TIC3X_REG_MAX)) + if (regno > (IS_CPU_TIC4X (tic4x_version) ? TIC4X_REG_MAX : TIC3X_REG_MAX)) return 0; if (info != NULL) - (*info->fprintf_func) (info->stream, "%s", registertable[regno]->name); + (*info->fprintf_func) (info->stream, "%s", registernames[regno]); return 1; } @@ -275,7 +275,7 @@ tic4x_print_cond (struct disassemble_info *info, unsigned int cond) if (condtable == NULL) { - condtable = xmalloc (sizeof (tic4x_cond_t *) * 32); + condtable = xcalloc (32, sizeof (tic4x_cond_t *)); for (i = 0; i < tic4x_num_conds; i++) condtable[tic4x_conds[i].cond] = (tic4x_cond_t *)(tic4x_conds + i); } @@ -639,9 +639,9 @@ tic4x_hash_opcode (tic4x_inst_t **optable, const tic4x_inst_t *inst, const unsigned long tic4x_oplevel) { - int j; - int opcode = inst->opcode >> (32 - TIC4X_HASH_SIZE); - int opmask = inst->opmask >> (32 - TIC4X_HASH_SIZE); + unsigned int j; + unsigned int opcode = inst->opcode >> (32 - TIC4X_HASH_SIZE); + unsigned int opmask = inst->opmask >> (32 - TIC4X_HASH_SIZE); /* Use a TIC4X_HASH_SIZE bit index as a hash index. We should have unique entries so there's no point having a linked list @@ -686,61 +686,75 @@ tic4x_disassemble (unsigned long pc, unsigned long instruction, struct disassemble_info *info) { - static tic4x_inst_t **optable = NULL; - static tic4x_inst_t **optable_special = NULL; tic4x_inst_t *p; int i; unsigned long tic4x_oplevel; - tic4x_version = info->mach; + if (tic4x_version != info->mach) + { + tic4x_version = info->mach; + /* Don't stash anything from a previous call using a different + machine. */ + if (optab) + { + free (optab); + optab = NULL; + } + if (optab_special) + { + free (optab_special); + optab_special = NULL; + } + registernames[REG_R0] = NULL; + } tic4x_oplevel = (IS_CPU_TIC4X (tic4x_version)) ? OP_C4X : 0; tic4x_oplevel |= OP_C3X | OP_LPWR | OP_IDLE2 | OP_ENH; - if (optable == NULL) + if (optab == NULL) { - optable = xcalloc (sizeof (tic4x_inst_t *), (1 << TIC4X_HASH_SIZE)); + optab = xcalloc (sizeof (tic4x_inst_t *), (1 << TIC4X_HASH_SIZE)); - optable_special = xcalloc (sizeof (tic4x_inst_t *), TIC4X_SPESOP_SIZE); + optab_special = xcalloc (sizeof (tic4x_inst_t *), TIC4X_SPESOP_SIZE); /* Install opcodes in reverse order so that preferred forms overwrite synonyms. */ for (i = tic4x_num_insts - 1; i >= 0; i--) - tic4x_hash_opcode (optable, optable_special, &tic4x_insts[i], + tic4x_hash_opcode (optab, optab_special, &tic4x_insts[i], tic4x_oplevel); /* We now need to remove the insn that are special from the - "normal" optable, to make the disasm search this extra list - for them. */ + "normal" optable, to make the disasm search this extra list + for them. */ for (i = 0; i < TIC4X_SPESOP_SIZE; i++) - if (optable_special[i] != NULL) - optable[optable_special[i]->opcode >> (32 - TIC4X_HASH_SIZE)] = NULL; + if (optab_special[i] != NULL) + optab[optab_special[i]->opcode >> (32 - TIC4X_HASH_SIZE)] = NULL; } /* See if we can pick up any loading of the DP register... */ if ((instruction >> 16) == 0x5070 || (instruction >> 16) == 0x1f70) tic4x_dp = EXTRU (instruction, 15, 0); - p = optable[instruction >> (32 - TIC4X_HASH_SIZE)]; + p = optab[instruction >> (32 - TIC4X_HASH_SIZE)]; if (p != NULL) { if (((instruction & p->opmask) == p->opcode) - && tic4x_print_op (NULL, instruction, p, pc)) - tic4x_print_op (info, instruction, p, pc); + && tic4x_print_op (NULL, instruction, p, pc)) + tic4x_print_op (info, instruction, p, pc); else - (*info->fprintf_func) (info->stream, "%08lx", instruction); + (*info->fprintf_func) (info->stream, "%08lx", instruction); } else { for (i = 0; iopcode == instruction) - { - (*info->fprintf_func)(info->stream, "%s", optable_special[i]->name); - break; - } + if (optab_special[i] != NULL + && optab_special[i]->opcode == instruction) + { + (*info->fprintf_func)(info->stream, "%s", optab_special[i]->name); + break; + } if (i == TIC4X_SPESOP_SIZE) - (*info->fprintf_func) (info->stream, "%08lx", instruction); + (*info->fprintf_func) (info->stream, "%08lx", instruction); } /* Return size of insn in words. */