From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17089 invoked by alias); 14 Aug 2012 00:14:16 -0000 Received: (qmail 17076 invoked by uid 22791); 14 Aug 2012 00:14:06 -0000 X-SWARE-Spam-Status: No, hits=-2.9 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,SARE_OBFU_PART_ORE X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 14 Aug 2012 00:13:48 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1T14lX-0006EN-40 from Maciej_Rozycki@mentor.com ; Mon, 13 Aug 2012 17:13:47 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Mon, 13 Aug 2012 17:13:46 -0700 Received: from [172.30.6.46] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Tue, 14 Aug 2012 01:13:44 +0100 Date: Tue, 14 Aug 2012 00:54:00 -0000 From: "Maciej W. Rozycki" To: CC: Richard Sandiford Subject: [PATCH] MIPS/opcodes: Streamline disassembler's operand processing Message-ID: User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2012-08/txt/msg00241.txt.bz2 Hi, This change updates standard-MIPS and MIPS16 instruction operand processing internals of the disassembler in line with the microMIPS version -- this includes the addition of the GET_OP macro and local variables for frequently accessed struct member references, all to improve readability and make maintenance easier, and perhaps to aid the compiler in making slightly better code. Additionally a GET_OP_S macro is added to simplify processing of sign extension across all the three instruction set handlers. No regressions across the 23 MIPS targets. OK to apply? Maciej 2012-08-14 Maciej W. Rozycki opcodes/ * mips-dis.c (print_insn_args): Add GET_OP and GET_OP_S local macros, use local variables for info struct member accesses, update the type of the variable used to hold the instruction word. (print_insn_mips, print_mips16_insn_arg): Likewise. (print_insn_mips16): Add GET_OP and GET_OP_S local macros, use local variables for info struct member accesses. (print_insn_micromips): Add GET_OP_S local macro. (_print_insn_mips): Update the type of the variable used to hold the instruction word. binutils-mips-dis-op.diff Index: binutils-fsf-trunk-quilt/opcodes/mips-dis.c =================================================================== --- binutils-fsf-trunk-quilt.orig/opcodes/mips-dis.c 2012-07-19 12:49:14.061767944 +0100 +++ binutils-fsf-trunk-quilt/opcodes/mips-dis.c 2012-07-19 12:49:34.431502283 +0100 @@ -930,16 +930,23 @@ lookup_mips_cp0sel_name (const struct mi static void print_insn_args (const char *d, - register unsigned long int l, + int l, bfd_vma pc, struct disassemble_info *info, const struct mips_opcode *opp) { - int op, delta; + const fprintf_ftype infprintf = info->fprintf_func; unsigned int lsb, msb, msbd; + void *is = info->stream; + int op; lsb = 0; +#define GET_OP(insn, field) \ + (((insn) >> OP_SH_##field) & OP_MASK_##field) +#define GET_OP_S(insn, field) \ + ((GET_OP (insn, field) ^ ((OP_MASK_##field >> 1) + 1)) \ + - ((OP_MASK_##field >> 1) + 1)) for (; *d != '\0'; d++) { switch (*d) @@ -949,7 +956,7 @@ print_insn_args (const char *d, case ')': case '[': case ']': - (*info->fprintf_func) (info->stream, "%c", *d); + infprintf (is, "%c", *d); break; case '+': @@ -959,44 +966,41 @@ print_insn_args (const char *d, { case '\0': /* xgettext:c-format */ - (*info->fprintf_func) (info->stream, - _("# internal error, incomplete extension sequence (+)")); + infprintf (is, + _("# internal error, " + "incomplete extension sequence (+)")); return; case 'A': - lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT; - (*info->fprintf_func) (info->stream, "0x%x", lsb); + lsb = GET_OP (l, SHAMT); + infprintf (is, "0x%x", lsb); break; case 'B': - msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB; - (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1); + msb = GET_OP (l, INSMSB); + infprintf (is, "0x%x", msb - lsb + 1); break; case '1': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI1) & OP_MASK_UDI1); + infprintf (is, "0x%x", GET_OP (l, UDI1)); break; case '2': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI2) & OP_MASK_UDI2); + infprintf (is, "0x%x", GET_OP (l, UDI2)); break; case '3': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI3) & OP_MASK_UDI3); + infprintf (is, "0x%x", GET_OP (l, UDI3)); break; case '4': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI4) & OP_MASK_UDI4); + infprintf (is, "0x%x", GET_OP (l, UDI4)); break; case 'C': case 'H': - msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD; - (*info->fprintf_func) (info->stream, "0x%x", msbd + 1); + msbd = GET_OP (l, EXTMSBD); + infprintf (is, "0x%x", msbd + 1); break; case 'D': @@ -1004,8 +1008,8 @@ print_insn_args (const char *d, const struct mips_cp0sel_name *n; unsigned int cp0reg, sel; - cp0reg = (l >> OP_SH_RD) & OP_MASK_RD; - sel = (l >> OP_SH_SEL) & OP_MASK_SEL; + cp0reg = GET_OP (l, RD); + sel = GET_OP (l, SEL); /* CP0 register including 'sel' code for mtcN (et al.), to be printed textually if known. If not known, print both @@ -1015,31 +1019,29 @@ print_insn_args (const char *d, n = lookup_mips_cp0sel_name(mips_cp0sel_names, mips_cp0sel_names_len, cp0reg, sel); if (n != NULL) - (*info->fprintf_func) (info->stream, "%s", n->name); + infprintf (is, "%s", n->name); else - (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel); + infprintf (is, "$%d,%d", cp0reg, sel); break; } case 'E': - lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32; - (*info->fprintf_func) (info->stream, "0x%x", lsb); + lsb = GET_OP (l, SHAMT) + 32; + infprintf (is, "0x%x", lsb); break; case 'F': - msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32; - (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1); + msb = GET_OP (l, INSMSB) + 32; + infprintf (is, "0x%x", msb - lsb + 1); break; case 'G': - msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32; - (*info->fprintf_func) (info->stream, "0x%x", msbd + 1); + msbd = GET_OP (l, EXTMSBD) + 32; + infprintf (is, "0x%x", msbd + 1); break; case 't': /* Coprocessor 0 reg name */ - (*info->fprintf_func) (info->stream, "%s", - mips_cp0_names[(l >> OP_SH_RT) & - OP_MASK_RT]); + infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]); break; case 'T': /* Coprocessor 0 reg name */ @@ -1047,8 +1049,8 @@ print_insn_args (const char *d, const struct mips_cp0sel_name *n; unsigned int cp0reg, sel; - cp0reg = (l >> OP_SH_RT) & OP_MASK_RT; - sel = (l >> OP_SH_SEL) & OP_MASK_SEL; + cp0reg = GET_OP (l, RT); + sel = GET_OP (l, SEL); /* CP0 register including 'sel' code for mftc0, to be printed textually if known. If not known, print both @@ -1058,228 +1060,173 @@ print_insn_args (const char *d, n = lookup_mips_cp0sel_name(mips_cp0sel_names, mips_cp0sel_names_len, cp0reg, sel); if (n != NULL) - (*info->fprintf_func) (info->stream, "%s", n->name); + infprintf (is, "%s", n->name); else - (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel); + infprintf (is, "$%d,%d", cp0reg, sel); break; } case 'x': /* bbit bit index */ - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_BBITIND) & OP_MASK_BBITIND); + infprintf (is, "0x%x", GET_OP (l, BBITIND)); break; case 'p': /* cins, cins32, exts and exts32 position */ - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CINSPOS) & OP_MASK_CINSPOS); + infprintf (is, "0x%x", GET_OP (l, CINSPOS)); break; case 's': /* cins and exts length-minus-one */ - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1); + infprintf (is, "0x%x", GET_OP (l, CINSLM1)); break; case 'S': /* cins32 and exts32 length-minus-one field */ - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1); + infprintf (is, "0x%x", GET_OP (l, CINSLM1)); break; case 'Q': /* seqi/snei immediate field */ - op = (l >> OP_SH_SEQI) & OP_MASK_SEQI; - /* Sign-extend it. */ - op = (op ^ 512) - 512; - (*info->fprintf_func) (info->stream, "%d", op); + infprintf (is, "%d", GET_OP_S (l, SEQI)); break; case 'a': /* 8-bit signed offset in bit 6 */ - delta = (l >> OP_SH_OFFSET_A) & OP_MASK_OFFSET_A; - if (delta & 0x80) - delta |= ~OP_MASK_OFFSET_A; - (*info->fprintf_func) (info->stream, "%d", delta); + infprintf (is, "%d", GET_OP_S (l, OFFSET_A)); break; case 'b': /* 8-bit signed offset in bit 3 */ - delta = (l >> OP_SH_OFFSET_B) & OP_MASK_OFFSET_B; - if (delta & 0x80) - delta |= ~OP_MASK_OFFSET_B; - (*info->fprintf_func) (info->stream, "%d", delta); + infprintf (is, "%d", GET_OP_S (l, OFFSET_B)); break; case 'c': /* 9-bit signed offset in bit 6 */ - delta = (l >> OP_SH_OFFSET_C) & OP_MASK_OFFSET_C; - if (delta & 0x100) - delta |= ~OP_MASK_OFFSET_C; /* Left shift 4 bits to print the real offset. */ - (*info->fprintf_func) (info->stream, "%d", delta << 4); + infprintf (is, "%d", GET_OP_S (l, OFFSET_C) << 4); break; case 'z': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RZ) & OP_MASK_RZ]); + infprintf (is, "%s", mips_gpr_names[GET_OP (l, RZ)]); break; case 'Z': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FZ) & OP_MASK_FZ]); + infprintf (is, "%s", mips_fpr_names[GET_OP (l, FZ)]); break; default: /* xgettext:c-format */ - (*info->fprintf_func) (info->stream, - _("# internal error, undefined extension sequence (+%c)"), - *d); + infprintf (is, + _("# internal error, " + "undefined extension sequence (+%c)"), + *d); return; } break; case '2': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_BP) & OP_MASK_BP); + infprintf (is, "0x%x", GET_OP (l, BP)); break; case '3': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_SA3) & OP_MASK_SA3); + infprintf (is, "0x%x", GET_OP (l, SA3)); break; case '4': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_SA4) & OP_MASK_SA4); + infprintf (is, "0x%x", GET_OP (l, SA4)); break; case '5': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_IMM8) & OP_MASK_IMM8); + infprintf (is, "0x%x", GET_OP (l, IMM8)); break; case '6': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_RS) & OP_MASK_RS); + infprintf (is, "0x%x", GET_OP (l, RS)); break; case '7': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_DSPACC) & OP_MASK_DSPACC); + infprintf (is, "$ac%d", GET_OP (l, DSPACC)); break; case '8': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_WRDSP) & OP_MASK_WRDSP); + infprintf (is, "0x%x", GET_OP (l, WRDSP)); break; case '9': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S); + infprintf (is, "$ac%d", GET_OP (l, DSPACC_S)); break; case '0': /* dsp 6-bit signed immediate in bit 20 */ - delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT); - if (delta & 0x20) /* test sign bit */ - delta |= ~OP_MASK_DSPSFT; - (*info->fprintf_func) (info->stream, "%d", delta); + infprintf (is, "%d", GET_OP_S (l, DSPSFT)); break; case ':': /* dsp 7-bit signed immediate in bit 19 */ - delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7); - if (delta & 0x40) /* test sign bit */ - delta |= ~OP_MASK_DSPSFT_7; - (*info->fprintf_func) (info->stream, "%d", delta); + infprintf (is, "%d", GET_OP_S (l, DSPSFT_7)); break; case '~': - delta = (l >> OP_SH_OFFSET12) & OP_MASK_OFFSET12; - if (delta & 0x800) - delta |= ~0x7ff; - (*info->fprintf_func) (info->stream, "%d", delta); + infprintf (is, "%d", GET_OP_S (l, OFFSET12)); break; case '\\': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_3BITPOS) & OP_MASK_3BITPOS); + infprintf (is, "0x%x", GET_OP (l, 3BITPOS)); break; case '\'': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_RDDSP) & OP_MASK_RDDSP); + infprintf (is, "0x%x", GET_OP (l, RDDSP)); break; case '@': /* dsp 10-bit signed immediate in bit 16 */ - delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10); - if (delta & 0x200) /* test sign bit */ - delta |= ~OP_MASK_IMM10; - (*info->fprintf_func) (info->stream, "%d", delta); + infprintf (is, "%d", GET_OP_S (l, IMM10)); break; case '!': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_MT_U) & OP_MASK_MT_U); + infprintf (is, "%d", GET_OP (l, MT_U)); break; case '$': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_MT_H) & OP_MASK_MT_H); + infprintf (is, "%d", GET_OP (l, MT_H)); break; case '*': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T); + infprintf (is, "$ac%d", GET_OP (l, MTACC_T)); break; case '&': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D); + infprintf (is, "$ac%d", GET_OP (l, MTACC_D)); break; case 'g': /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */ - (*info->fprintf_func) (info->stream, "$%ld", - (l >> OP_SH_RD) & OP_MASK_RD); + infprintf (is, "$%d", GET_OP (l, RD)); break; case 's': case 'b': case 'r': case 'v': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]); + infprintf (is, "%s", mips_gpr_names[GET_OP (l, RS)]); break; case 't': case 'w': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); + infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]); break; case 'i': case 'u': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE); + infprintf (is, "0x%x", GET_OP (l, IMMEDIATE)); break; case 'j': /* Same as i, but sign-extended. */ case 'o': - delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; - if (delta & 0x8000) - delta |= ~0xffff; - (*info->fprintf_func) (info->stream, "%d", - delta); + infprintf (is, "%d", GET_OP_S (l, DELTA)); break; case 'h': - (*info->fprintf_func) (info->stream, "0x%x", - (unsigned int) ((l >> OP_SH_PREFX) - & OP_MASK_PREFX)); + infprintf (is, "0x%x", GET_OP (l, PREFX)); break; case 'k': - (*info->fprintf_func) (info->stream, "0x%x", - (unsigned int) ((l >> OP_SH_CACHE) - & OP_MASK_CACHE)); + infprintf (is, "0x%x", GET_OP (l, CACHE)); break; case 'a': info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff) - | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)); + | (GET_OP (l, TARGET) << 2)); /* For gdb disassembler, force odd address on jalx. */ if (info->flavour == bfd_target_unknown_flavour && strcmp (opp->name, "jalx") == 0) @@ -1289,97 +1236,80 @@ print_insn_args (const char *d, case 'p': /* Sign extend the displacement. */ - delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; - if (delta & 0x8000) - delta |= ~0xffff; - info->target = (delta << 2) + pc + INSNLEN; + info->target = (GET_OP_S (l, DELTA) << 2) + pc + INSNLEN; (*info->print_address_func) (info->target, info); break; case 'd': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]); + infprintf (is, "%s", mips_gpr_names[GET_OP (l, RD)]); break; case 'U': { /* First check for both rd and rt being equal. */ - unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD; - if (reg == ((l >> OP_SH_RT) & OP_MASK_RT)) - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[reg]); + unsigned int reg = GET_OP (l, RD); + if (reg == GET_OP (l, RT)) + infprintf (is, "%s", mips_gpr_names[reg]); else { /* If one is zero use the other. */ if (reg == 0) - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); - else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0) - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[reg]); + infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]); + else if (GET_OP (l, RT) == 0) + infprintf (is, "%s", mips_gpr_names[reg]); else /* Bogus, result depends on processor. */ - (*info->fprintf_func) (info->stream, "%s or %s", - mips_gpr_names[reg], - mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); + infprintf (is, "%s or %s", + mips_gpr_names[reg], + mips_gpr_names[GET_OP (l, RT)]); } } break; case 'z': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]); + infprintf (is, "%s", mips_gpr_names[0]); break; case '<': case '1': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_SHAMT) & OP_MASK_SHAMT); + infprintf (is, "0x%x", GET_OP (l, SHAMT)); break; case 'c': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CODE) & OP_MASK_CODE); + infprintf (is, "0x%x", GET_OP (l, CODE)); break; case 'q': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CODE2) & OP_MASK_CODE2); + infprintf (is, "0x%x", GET_OP (l, CODE2)); break; case 'C': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_COPZ) & OP_MASK_COPZ); + infprintf (is, "0x%x", GET_OP (l, COPZ)); break; case 'B': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CODE20) & OP_MASK_CODE20); + infprintf (is, "0x%x", GET_OP (l, CODE20)); break; case 'J': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CODE19) & OP_MASK_CODE19); + infprintf (is, "0x%x", GET_OP (l, CODE19)); break; case 'S': case 'V': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]); + infprintf (is, "%s", mips_fpr_names[GET_OP (l, FS)]); break; case 'T': case 'W': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]); + infprintf (is, "%s", mips_fpr_names[GET_OP (l, FT)]); break; case 'D': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]); + infprintf (is, "%s", mips_fpr_names[GET_OP (l, FD)]); break; case 'R': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]); + infprintf (is, "%s", mips_fpr_names[GET_OP (l, FR)]); break; case 'E': @@ -1390,8 +1320,7 @@ print_insn_args (const char *d, 'T' format. Therefore, until we gain understanding of cp2 register names, we can simply print the register numbers. */ - (*info->fprintf_func) (info->stream, "$%ld", - (l >> OP_SH_RT) & OP_MASK_RT); + infprintf (is, "$%d", GET_OP (l, RT)); break; case 'G': @@ -1399,60 +1328,50 @@ print_insn_args (const char *d, that FPU (cp1) instructions disassemble this field using 'S' format. Therefore, we only need to worry about cp0, cp2, and cp3. */ - op = (l >> OP_SH_OP) & OP_MASK_OP; + op = GET_OP (l, OP); if (op == OP_OP_COP0) - (*info->fprintf_func) (info->stream, "%s", - mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]); + infprintf (is, "%s", mips_cp0_names[GET_OP (l, RD)]); else - (*info->fprintf_func) (info->stream, "$%ld", - (l >> OP_SH_RD) & OP_MASK_RD); + infprintf (is, "$%d", GET_OP (l, RD)); break; case 'K': - (*info->fprintf_func) (info->stream, "%s", - mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]); + infprintf (is, "%s", mips_hwr_names[GET_OP (l, RD)]); break; case 'N': - (*info->fprintf_func) (info->stream, - ((opp->pinfo & (FP_D | FP_S)) != 0 - ? "$fcc%ld" : "$cc%ld"), - (l >> OP_SH_BCC) & OP_MASK_BCC); + infprintf (is, + (opp->pinfo & (FP_D | FP_S)) != 0 ? "$fcc%d" : "$cc%d", + GET_OP (l, BCC)); break; case 'M': - (*info->fprintf_func) (info->stream, "$fcc%ld", - (l >> OP_SH_CCC) & OP_MASK_CCC); + infprintf (is, "$fcc%d", GET_OP (l, CCC)); break; case 'P': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_PERFREG) & OP_MASK_PERFREG); + infprintf (is, "%d", GET_OP (l, PERFREG)); break; case 'e': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE); + infprintf (is, "%d", GET_OP (l, VECBYTE)); break; case '%': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN); + infprintf (is, "%d", GET_OP (l, VECALIGN)); break; case 'H': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_SEL) & OP_MASK_SEL); + infprintf (is, "%d", GET_OP (l, SEL)); break; case 'O': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_ALN) & OP_MASK_ALN); + infprintf (is, "%d", GET_OP (l, ALN)); break; case 'Q': { - unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL; + unsigned int vsel = GET_OP (l, VSEL); if ((vsel & 0x10) == 0) { @@ -1462,43 +1381,34 @@ print_insn_args (const char *d, for (fmt = 0; fmt < 3; fmt++, vsel >>= 1) if ((vsel & 1) == 0) break; - (*info->fprintf_func) (info->stream, "$v%ld[%d]", - (l >> OP_SH_FT) & OP_MASK_FT, - vsel >> 1); + infprintf (is, "$v%d[%d]", GET_OP (l, FT), vsel >> 1); } else if ((vsel & 0x08) == 0) { - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FT) & OP_MASK_FT); + infprintf (is, "$v%d", GET_OP (l, FT)); } else { - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_FT) & OP_MASK_FT); + infprintf (is, "0x%x", GET_OP (l, FT)); } } break; case 'X': - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FD) & OP_MASK_FD); + infprintf (is, "$v%d", GET_OP (l, FD)); break; case 'Y': - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FS) & OP_MASK_FS); + infprintf (is, "$v%d", GET_OP (l, FS)); break; case 'Z': - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FT) & OP_MASK_FT); + infprintf (is, "$v%d", GET_OP (l, FT)); break; default: /* xgettext:c-format */ - (*info->fprintf_func) (info->stream, - _("# internal error, undefined modifier (%c)"), - *d); + infprintf (is, _("# internal error, undefined modifier (%c)"), *d); return; } } @@ -1511,12 +1421,14 @@ print_insn_args (const char *d, static int print_insn_mips (bfd_vma memaddr, - unsigned long int word, + int word, struct disassemble_info *info) { + static const struct mips_opcode *mips_hash[OP_MASK_OP + 1]; + const fprintf_ftype infprintf = info->fprintf_func; const struct mips_opcode *op; static bfd_boolean init = 0; - static const struct mips_opcode *mips_hash[OP_MASK_OP + 1]; + void *is = info->stream; /* Build a hash table to shorten the search time. */ if (! init) @@ -1530,7 +1442,7 @@ print_insn_mips (bfd_vma memaddr, if (op->pinfo == INSN_MACRO || (no_aliases && (op->pinfo2 & INSN2_ALIAS))) continue; - if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)) + if (i == GET_OP (op->match, OP)) { mips_hash[i] = op; break; @@ -1550,7 +1462,7 @@ print_insn_mips (bfd_vma memaddr, info->target = 0; info->target2 = 0; - op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP]; + op = mips_hash[GET_OP (word, OP)]; if (op != NULL) { for (; op < &mips_opcodes[NUMOPCODES]; op++) @@ -1589,12 +1501,12 @@ print_insn_mips (bfd_vma memaddr, | INSN_LOAD_MEMORY_DELAY)) != 0) info->insn_type = dis_dref; - (*info->fprintf_func) (info->stream, "%s", op->name); + infprintf (is, "%s", op->name); d = op->args; if (d != NULL && *d != '\0') { - (*info->fprintf_func) (info->stream, "\t"); + infprintf (is, "\t"); print_insn_args (d, word, memaddr, info, op); } @@ -1602,10 +1514,12 @@ print_insn_mips (bfd_vma memaddr, } } } +#undef GET_OP_S +#undef GET_OP /* Handle undefined instructions. */ info->insn_type = dis_noninsn; - (*info->fprintf_func) (info->stream, "0x%lx", word); + infprintf (is, "0x%x", word); return INSNLEN; } @@ -1620,65 +1534,62 @@ print_mips16_insn_arg (char type, bfd_vma memaddr, struct disassemble_info *info) { + const fprintf_ftype infprintf = info->fprintf_func; + void *is = info->stream; + +#define GET_OP(insn, field) \ + (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field) +#define GET_OP_S(insn, field) \ + ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \ + - ((MIPS16OP_MASK_##field >> 1) + 1)) switch (type) { case ',': case '(': case ')': - (*info->fprintf_func) (info->stream, "%c", type); + infprintf (is, "%c", type); break; case 'y': case 'w': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_RY) - & MIPS16OP_MASK_RY))); + infprintf (is, "%s", mips16_reg_names (GET_OP (l, RY))); break; case 'x': case 'v': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_RX) - & MIPS16OP_MASK_RX))); + infprintf (is, "%s", mips16_reg_names (GET_OP (l, RX))); break; case 'z': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_RZ) - & MIPS16OP_MASK_RZ))); + infprintf (is, "%s", mips16_reg_names (GET_OP (l, RZ))); break; case 'Z': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_MOVE32Z) - & MIPS16OP_MASK_MOVE32Z))); + infprintf (is, "%s", mips16_reg_names (GET_OP (l, MOVE32Z))); break; case '0': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]); + infprintf (is, "%s", mips_gpr_names[0]); break; case 'S': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]); + infprintf (is, "%s", mips_gpr_names[29]); break; case 'P': - (*info->fprintf_func) (info->stream, "$pc"); + infprintf (is, "$pc"); break; case 'R': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]); + infprintf (is, "%s", mips_gpr_names[31]); break; case 'X': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[((l >> MIPS16OP_SH_REGR32) - & MIPS16OP_MASK_REGR32)]); + infprintf (is, "%s", mips_gpr_names[GET_OP (l, REGR32)]); break; case 'Y': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]); + infprintf (is, "%s", mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]); break; case '<': @@ -1716,51 +1627,51 @@ print_mips16_insn_arg (char type, { case '<': nbits = 3; - immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ; + immed = GET_OP (l, RZ); extbits = 5; extu = 1; break; case '>': nbits = 3; - immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX; + immed = GET_OP (l, RX); extbits = 5; extu = 1; break; case '[': nbits = 3; - immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ; + immed = GET_OP (l, RZ); extbits = 6; extu = 1; break; case ']': nbits = 3; - immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX; + immed = GET_OP (l, RX); extbits = 6; extu = 1; break; case '4': nbits = 4; - immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4; + immed = GET_OP (l, IMM4); signedp = 1; extbits = 15; break; case '5': nbits = 5; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; + immed = GET_OP (l, IMM5); info->insn_type = dis_dref; info->data_size = 1; break; case 'H': nbits = 5; shift = 1; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; + immed = GET_OP (l, IMM5); info->insn_type = dis_dref; info->data_size = 2; break; case 'W': nbits = 5; shift = 2; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; + immed = GET_OP (l, IMM5); if ((op->pinfo & MIPS16_INSN_READ_PC) == 0 && (op->pinfo & MIPS16_INSN_READ_SP) == 0) { @@ -1771,27 +1682,27 @@ print_mips16_insn_arg (char type, case 'D': nbits = 5; shift = 3; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; + immed = GET_OP (l, IMM5); info->insn_type = dis_dref; info->data_size = 8; break; case 'j': nbits = 5; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; + immed = GET_OP (l, IMM5); signedp = 1; break; case '6': nbits = 6; - immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6; + immed = GET_OP (l, IMM6); break; case '8': nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); break; case 'V': nbits = 8; shift = 2; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); /* FIXME: This might be lw, or it might be addiu to $sp or $pc. We assume it's load. */ info->insn_type = dis_dref; @@ -1800,36 +1711,36 @@ print_mips16_insn_arg (char type, case 'C': nbits = 8; shift = 3; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); info->insn_type = dis_dref; info->data_size = 8; break; case 'U': nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); extu = 1; break; case 'k': nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); signedp = 1; break; case 'K': nbits = 8; shift = 3; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); signedp = 1; break; case 'p': nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); signedp = 1; pcrel = 1; branch = 1; break; case 'q': nbits = 11; - immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11; + immed = GET_OP (l, IMM11); signedp = 1; pcrel = 1; branch = 1; @@ -1837,7 +1748,7 @@ print_mips16_insn_arg (char type, case 'A': nbits = 8; shift = 2; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; + immed = GET_OP (l, IMM8); pcrel = 1; /* FIXME: This can be lw or la. We assume it is lw. */ info->insn_type = dis_dref; @@ -1846,7 +1757,7 @@ print_mips16_insn_arg (char type, case 'B': nbits = 5; shift = 3; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; + immed = GET_OP (l, IMM5); pcrel = 1; info->insn_type = dis_dref; info->data_size = 8; @@ -1854,7 +1765,7 @@ print_mips16_insn_arg (char type, case 'E': nbits = 5; shift = 2; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; + immed = GET_OP (l, IMM5); pcrel = 1; break; default: @@ -1884,7 +1795,7 @@ print_mips16_insn_arg (char type, } if (! pcrel) - (*info->fprintf_func) (info->stream, "%d", immed); + infprintf (is, "%d", immed); else { bfd_vma baseaddr; @@ -1962,51 +1873,43 @@ print_mips16_insn_arg (char type, need_comma = 0; - l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6; + l = GET_OP (l, IMM6); amask = (l >> 3) & 7; if (amask > 0 && amask < 5) { - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]); + infprintf (is, "%s", mips_gpr_names[4]); if (amask > 1) - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[amask + 3]); + infprintf (is, "-%s", mips_gpr_names[amask + 3]); need_comma = 1; } smask = (l >> 1) & 3; if (smask == 3) { - (*info->fprintf_func) (info->stream, "%s??", - need_comma ? "," : ""); + infprintf (is, "%s??", need_comma ? "," : ""); need_comma = 1; } else if (smask > 0) { - (*info->fprintf_func) (info->stream, "%s%s", - need_comma ? "," : "", - mips_gpr_names[16]); + infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[16]); if (smask > 1) - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[smask + 15]); + infprintf (is, "-%s", mips_gpr_names[smask + 15]); need_comma = 1; } if (l & 1) { - (*info->fprintf_func) (info->stream, "%s%s", - need_comma ? "," : "", - mips_gpr_names[31]); + infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[31]); need_comma = 1; } if (amask == 5 || amask == 6) { - (*info->fprintf_func) (info->stream, "%s$f0", - need_comma ? "," : ""); + infprintf (is, "%s$f0", need_comma ? "," : ""); if (amask == 6) - (*info->fprintf_func) (info->stream, "-$f1"); + infprintf (is, "-$f1"); } } break; @@ -2043,10 +1946,9 @@ print_mips16_insn_arg (char type, } if (args > 0) { - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]); + infprintf (is, "%s", mips_gpr_names[4]); if (args > 1) - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[4 + args - 1]); + infprintf (is, "-%s", mips_gpr_names[4 + args - 1]); need_comma = 1; } @@ -2054,12 +1956,10 @@ print_mips16_insn_arg (char type, if (framesz == 0 && !use_extend) framesz = 128; - (*info->fprintf_func) (info->stream, "%s%d", - need_comma ? "," : "", - framesz); + infprintf (is, "%s%d", need_comma ? "," : "", framesz); if (l & 0x40) /* $ra */ - (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[31]); + infprintf (is, ",%s", mips_gpr_names[31]); nsreg = (l >> 24) & 0x7; smask = 0; @@ -2075,34 +1975,32 @@ print_mips16_insn_arg (char type, { if (smask & (1 << i)) { - (*info->fprintf_func) (info->stream, ",%s", - mips_gpr_names[i == 8 ? 30 : (16 + i)]); + infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]); /* Skip over string of set bits. */ for (j = i; smask & (2 << j); j++) continue; if (j > i) - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[j == 8 ? 30 : (16 + j)]); + infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]); i = j + 1; } } /* Statics $ax - $a3. */ if (statics == 1) - (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[7]); + infprintf (is, ",%s", mips_gpr_names[7]); else if (statics > 0) - (*info->fprintf_func) (info->stream, ",%s-%s", - mips_gpr_names[7 - statics + 1], - mips_gpr_names[7]); + infprintf (is, ",%s-%s", + mips_gpr_names[7 - statics + 1], + mips_gpr_names[7]); } break; default: /* xgettext:c-format */ - (*info->fprintf_func) - (info->stream, - _("# internal disassembler error, unrecognised modifier (%c)"), - type); + infprintf (is, + _("# internal disassembler error, " + "unrecognised modifier (%c)"), + type); abort (); } } @@ -2112,6 +2010,7 @@ print_mips16_insn_arg (char type, static int print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info) { + const fprintf_ftype infprintf = info->fprintf_func; int status; bfd_byte buffer[2]; int length; @@ -2119,6 +2018,7 @@ print_insn_mips16 (bfd_vma memaddr, stru bfd_boolean use_extend; int extend = 0; const struct mips_opcode *op, *opend; + void *is = info->stream; info->bytes_per_chunk = 2; info->display_endian = info->endian; @@ -2155,8 +2055,7 @@ print_insn_mips16 (bfd_vma memaddr, stru status = (*info->read_memory_func) (memaddr, buffer, 2, info); if (status != 0) { - (*info->fprintf_func) (info->stream, "extend 0x%x", - (unsigned int) extend); + infprintf (is, "extend 0x%x", (unsigned int) extend); (*info->memory_error_func) (status, memaddr, info); return -1; } @@ -2169,8 +2068,7 @@ print_insn_mips16 (bfd_vma memaddr, stru /* Check for an extend opcode followed by an extend opcode. */ if ((insn & 0xf800) == 0xf000) { - (*info->fprintf_func) (info->stream, "extend 0x%x", - (unsigned int) extend); + infprintf (is, "extend 0x%x", (unsigned int) extend); info->insn_type = dis_noninsn; return length; } @@ -2193,8 +2091,7 @@ print_insn_mips16 (bfd_vma memaddr, stru { if (use_extend) { - (*info->fprintf_func) (info->stream, "extend 0x%x", - (unsigned int) extend); + infprintf (is, "extend 0x%x", (unsigned int) extend); info->insn_type = dis_noninsn; return length - 2; } @@ -2216,16 +2113,15 @@ print_insn_mips16 (bfd_vma memaddr, stru } } - (*info->fprintf_func) (info->stream, "%s", op->name); + infprintf (is, "%s", op->name); if (op->args[0] != '\0') - (*info->fprintf_func) (info->stream, "\t"); + infprintf (is, "\t"); for (s = op->args; *s != '\0'; s++) { if (*s == ',' && s[1] == 'w' - && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX) - == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY))) + && GET_OP (insn, RX) == GET_OP (insn, RY)) { /* Skip the register and the comma. */ ++s; @@ -2233,8 +2129,7 @@ print_insn_mips16 (bfd_vma memaddr, stru } if (*s == ',' && s[1] == 'v' - && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ) - == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX))) + && GET_OP (insn, RZ) == GET_OP (insn, RX)) { /* Skip the register and the comma. */ ++s; @@ -2261,10 +2156,12 @@ print_insn_mips16 (bfd_vma memaddr, stru return length; } } +#undef GET_OP_S +#undef GET_OP if (use_extend) - (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000); - (*info->fprintf_func) (info->stream, "0x%x", insn); + infprintf (is, "0x%x", extend | 0xf000); + infprintf (is, "0x%x", insn); info->insn_type = dis_noninsn; return length; @@ -2375,6 +2272,9 @@ print_insn_micromips (bfd_vma memaddr, s #define GET_OP(insn, field) \ (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field) +#define GET_OP_S(insn, field) \ + ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \ + - ((MICROMIPSOP_MASK_##field >> 1) + 1)) opend = micromips_opcodes + bfd_micromips_num_opcodes; for (op = micromips_opcodes; op < opend; op++) { @@ -2401,10 +2301,7 @@ print_insn_micromips (bfd_vma memaddr, s break; case '.': - delta = GET_OP (insn, OFFSET10); - if (delta & 0x200) - delta |= ~0x3ff; - infprintf (is, "%d", delta); + infprintf (is, "%d", GET_OP_S (insn, OFFSET10)); break; case '1': @@ -2461,10 +2358,7 @@ print_insn_micromips (bfd_vma memaddr, s break; case '~': - delta = GET_OP (insn, OFFSET12); - if (delta & 0x800) - delta |= ~0x7ff; - infprintf (is, "%d", delta); + infprintf (is, "%d", GET_OP_S (insn, OFFSET12)); break; case 'a': @@ -2473,7 +2367,7 @@ print_insn_micromips (bfd_vma memaddr, s | (GET_OP (insn, TARGET) << 2)); else info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff) - | ((GET_OP (insn, TARGET)) << 1)); + | (GET_OP (insn, TARGET) << 1)); /* For gdb disassembler, force odd address on jalx. */ if (info->flavour == bfd_target_unknown_flavour && strcmp (op->name, "jalx") == 0) @@ -2507,8 +2401,7 @@ print_insn_micromips (bfd_vma memaddr, s case 'j': /* Same as i, but sign-extended. */ case 'o': - delta = (GET_OP (insn, DELTA) ^ 0x8000) - 0x8000; - infprintf (is, "%d", delta); + infprintf (is, "%d", GET_OP_S (insn, DELTA)); break; case 'k': @@ -2550,7 +2443,7 @@ print_insn_micromips (bfd_vma memaddr, s case 'p': /* Sign-extend the displacement. */ - delta = (GET_OP (insn, DELTA) ^ 0x8000) - 0x8000; + delta = GET_OP_S (insn, DELTA); info->target = (delta << 1) + memaddr + length; (*info->print_address_func) (info->target, info); break; @@ -2824,7 +2717,7 @@ print_insn_micromips (bfd_vma memaddr, s case 'A': /* Sign-extend the immediate. */ - immed = ((GET_OP (insn, IMMA) ^ 0x40) - 0x40) << 2; + immed = GET_OP_S (insn, IMMA) << 2; infprintf (is, "%d", immed); break; @@ -2840,14 +2733,14 @@ print_insn_micromips (bfd_vma memaddr, s case 'D': /* Sign-extend the displacement. */ - delta = (GET_OP (insn, IMMD) ^ 0x200) - 0x200; + delta = GET_OP_S (insn, IMMD); info->target = (delta << 1) + memaddr + length; (*info->print_address_func) (info->target, info); break; case 'E': /* Sign-extend the displacement. */ - delta = (GET_OP (insn, IMME) ^ 0x40) - 0x40; + delta = GET_OP_S (insn, IMME); info->target = (delta << 1) + memaddr + length; (*info->print_address_func) (info->target, info); break; @@ -2915,8 +2808,7 @@ print_insn_micromips (bfd_vma memaddr, s case 'Q': /* Sign-extend the immediate. */ - immed = (GET_OP (insn, IMMQ) ^ 0x400000) - 0x400000; - immed <<= 2; + immed = GET_OP_S (insn, IMMQ) << 2; infprintf (is, "%d", immed); break; @@ -2932,16 +2824,15 @@ print_insn_micromips (bfd_vma memaddr, s case 'X': /* Sign-extend the immediate. */ - immed = (GET_OP (insn, IMMX) ^ 0x8) - 0x8; + immed = GET_OP_S (insn, IMMX); infprintf (is, "%d", immed); break; case 'Y': /* Sign-extend the immediate. */ - immed = (GET_OP (insn, IMMY) ^ 0x100) - 0x100; - if (immed >= -2 && immed <= 1) - immed ^= 0x100; - immed = immed << 2; + immed = GET_OP_S (insn, IMMY) << 2; + if ((unsigned int) (immed + 8) < 16) + immed ^= 0x400; infprintf (is, "%d", immed); break; @@ -2992,6 +2883,7 @@ print_insn_micromips (bfd_vma memaddr, s return length; } } +#undef GET_OP_S #undef GET_OP infprintf (is, "0x%x", insn); @@ -3073,12 +2965,12 @@ _print_insn_mips (bfd_vma memaddr, status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info); if (status == 0) { - unsigned long insn; + int insn; if (endianness == BFD_ENDIAN_BIG) - insn = (unsigned long) bfd_getb32 (buffer); + insn = bfd_getb32 (buffer); else - insn = (unsigned long) bfd_getl32 (buffer); + insn = bfd_getl32 (buffer); return print_insn_mips (memaddr, insn, info); }