From 27c5c572c911ec2f77bab953586870919db15a29 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 7 Jul 2013 09:50:43 +0000 Subject: [PATCH] include/opcode/ * mips.h: Document "+i". opcodes/ * mips-opc.c (mips_builtin_opcodes): Use "+i" rather than "a" for "jalx". * mips16-opc.c (mips16_opcodes): Likewise. * micromips-opc.c (micromips_opcodes): Likewise. * mips-dis.c (print_insn_args, print_mips16_insn_arg) (print_insn_mips16): Handle "+i". (print_insn_micromips): Likewise. Conditionally preserve the ISA bit for "a" but not for "+i". gas/ * config/tc-mips.c (validate_mips_insn, validate_micromips_insn): (mips_ip, mips16_ip): Handle "+i". --- gas/ChangeLog | 5 +++++ gas/config/tc-mips.c | 7 +++++++ include/opcode/ChangeLog | 4 ++++ include/opcode/mips.h | 9 ++++++--- opcodes/ChangeLog | 11 +++++++++++ opcodes/micromips-opc.c | 2 +- opcodes/mips-dis.c | 39 ++++++++++++++++++++++----------------- opcodes/mips-opc.c | 2 +- opcodes/mips16-opc.c | 2 +- 9 files changed, 58 insertions(+), 23 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 2e55824fd39..3450c839c21 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2013-07-07 Richard Sandiford + + * config/tc-mips.c (validate_mips_insn, validate_micromips_insn): + (mips_ip, mips16_ip): Handle "+i". + 2013-07-07 Richard Sandiford * config/tc-mips.c (mips32_to_micromips_reg_h_map): Delete. diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index f9cf758fc13..9d058afb891 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -10910,6 +10910,7 @@ validate_mips_insn (const struct mips_opcode *opc) case 'a': USE_BITS (OP_MASK_OFFSET_A, OP_SH_OFFSET_A); break; case 'b': USE_BITS (OP_MASK_OFFSET_B, OP_SH_OFFSET_B); break; case 'c': USE_BITS (OP_MASK_OFFSET_C, OP_SH_OFFSET_C); break; + case 'i': USE_BITS (OP_MASK_TARGET, OP_SH_TARGET); break; case 'j': USE_BITS (OP_MASK_EVAOFFSET, OP_SH_EVAOFFSET); break; default: @@ -11071,6 +11072,7 @@ validate_micromips_insn (const struct mips_opcode *opc) case 'F': USE_BITS (INSMSB); break; case 'G': USE_BITS (EXTMSBD); break; case 'H': USE_BITS (EXTMSBD); break; + case 'i': USE_BITS (TARGET); break; case 'j': USE_BITS (EVAOFFSET); break; default: as_bad (_("Internal error: bad mips opcode " @@ -12173,6 +12175,9 @@ mips_ip (char *str, struct mips_cl_insn *ip) INSERT_OPERAND (0, FZ, *ip, regno); continue; + case 'i': + goto jump; + case 'j': { int shift = 8; @@ -13031,6 +13036,7 @@ mips_ip (char *str, struct mips_cl_insn *ip) continue; case 'a': /* 26-bit address. */ + jump: *offset_reloc = BFD_RELOC_MIPS_JMP; my_getExpression (&offset_expr, s); s = expr_end; @@ -14280,6 +14286,7 @@ mips16_ip (char *str, struct mips_cl_insn *ip) continue; case 'a': /* 26 bit address */ + case 'i': my_getExpression (&offset_expr, s); s = expr_end; *offset_reloc = BFD_RELOC_MIPS16_JMP; diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index f132fd39045..b2b718cb49c 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2013-07-07 Richard Sandiford + + * mips.h: Document "+i". + 2013-07-07 Richard Sandiford * mips.h: Remove "mi" documentation. Update "mh" documentation. diff --git a/include/opcode/mips.h b/include/opcode/mips.h index 4dfec6c9955..d25b1368700 100644 --- a/include/opcode/mips.h +++ b/include/opcode/mips.h @@ -379,6 +379,7 @@ struct mips_opcode "<" 5 bit shift amount (OP_*_SHAMT) ">" shift amount between 32 and 63, stored after subtracting 32 (OP_*_SHAMT) "a" 26 bit target address (OP_*_TARGET) + "+i" likewise, but flips bit 0 "b" 5 bit base register (OP_*_RS) "c" 10 bit breakpoint code (OP_*_CODE) "d" 5 bit destination register specifier (OP_*_RD) @@ -539,7 +540,7 @@ struct mips_opcode following), for quick reference when adding more: "1234" "ABCEFGHIJPQSXZ" - "abcjpstxz" + "abcijpstxz" */ /* These are the bits which may be set in the pinfo field of an @@ -1383,6 +1384,7 @@ extern int bfd_mips_num_opcodes; "Y" 5 bit MIPS register (MIPS16OP_*_REG32R) "6" 6 bit unsigned break code (MIPS16OP_*_IMM6) "a" 26 bit jump address + "i" likewise, but flips bit 0 "e" 11 bit extension value "l" register list for entry instruction "L" register list for exit instruction @@ -1741,6 +1743,7 @@ extern const int bfd_mips16_num_opcodes; "|" 4-bit trap code (MICROMIPSOP_*_TRAP) "~" 12-bit signed offset (MICROMIPSOP_*_OFFSET12) "a" 26-bit target address (MICROMIPSOP_*_TARGET) + "+i" likewise, but flips bit 0 "b" 5-bit base register (MICROMIPSOP_*_RS) "c" 10-bit higher breakpoint code (MICROMIPSOP_*_CODE) "d" 5-bit destination register specifier (MICROMIPSOP_*_RD) @@ -1846,10 +1849,10 @@ extern const int bfd_mips16_num_opcodes; Extension character sequences used so far ("+" followed by the following), for quick reference when adding more: - "j" "" - "ABCEFGHI" "" + "ABCEFGHI" + "ij" Extension character sequences used so far ("m" followed by the following), for quick reference when adding more: diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 8b10771fbbf..68b263f3c32 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,14 @@ +2013-07-07 Richard Sandiford + + * mips-opc.c (mips_builtin_opcodes): Use "+i" rather than "a" for + "jalx". + * mips16-opc.c (mips16_opcodes): Likewise. + * micromips-opc.c (micromips_opcodes): Likewise. + * mips-dis.c (print_insn_args, print_mips16_insn_arg) + (print_insn_mips16): Handle "+i". + (print_insn_micromips): Likewise. Conditionally preserve the + ISA bit for "a" but not for "+i". + 2013-07-07 Richard Sandiford * micromips-opc.c (WR_mhi): Rename to.. diff --git a/opcodes/micromips-opc.c b/opcodes/micromips-opc.c index 9a9a32cc5ad..6a7239629d1 100644 --- a/opcodes/micromips-opc.c +++ b/opcodes/micromips-opc.c @@ -587,7 +587,7 @@ const struct mips_opcode micromips_opcodes[] = {"jals", "s", 0, (int) M_JALS_1, INSN_MACRO, 0, I1 }, {"jals", "a", 0, (int) M_JALS_A, INSN_MACRO, 0, I1 }, {"jals", "a", 0x74000000, 0xfc000000, UBD|WR_31, BD16, I1 }, -{"jalx", "a", 0xf0000000, 0xfc000000, UBD|WR_31, BD32, I1 }, +{"jalx", "+i", 0xf0000000, 0xfc000000, UBD|WR_31, BD32, I1 }, {"la", "t,A(b)", 0, (int) M_LA_AB, INSN_MACRO, 0, I1 }, {"lb", "t,o(b)", 0x1c000000, 0xfc000000, RD_b|WR_t, 0, I1 }, {"lb", "t,A(b)", 0, (int) M_LB_AB, INSN_MACRO, 0, I1 }, diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index 4d89220edd8..9ef7247bf23 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -1105,6 +1105,15 @@ print_insn_args (const char *d, infprintf (is, "%s", mips_fpr_names[GET_OP (l, FZ)]); break; + case 'i': /* JALX destination */ + info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff) + | (GET_OP (l, TARGET) << 2)); + /* For gdb disassembler, force odd address on jalx. */ + if (info->flavour == bfd_target_unknown_flavour) + info->target |= 1; + (*info->print_address_func) (info->target, info); + break; + case 'j': /* 9-bit signed offset in bit 7. */ infprintf (is, "%d", GET_OP_S (l, EVAOFFSET)); break; @@ -1229,10 +1238,6 @@ print_insn_args (const char *d, case 'a': info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff) | (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) - info->target |= 1; (*info->print_address_func) (info->target, info); break; @@ -1874,13 +1879,12 @@ print_mips16_insn_arg (char type, break; case 'a': + case 'i': { - int jalx = l & 0x400; - if (! use_extend) extend = 0; l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2); - if (!jalx && info->flavour == bfd_target_unknown_flavour) + if (type == 'a' && info->flavour == bfd_target_unknown_flavour) /* For gdb disassembler, maintain odd address. */ l |= 1; } @@ -2147,7 +2151,7 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info) { const char *s; - if (strchr (op->args, 'a') != NULL) + if (op->args[0] == 'a' || op->args[0] == 'i') { if (use_extend) { @@ -2422,15 +2426,10 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) break; case 'a': - if (strcmp (op->name, "jalx") == 0) - info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff) - | (GET_OP (insn, TARGET) << 2)); - else - info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff) - | (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) + info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff) + | (GET_OP (insn, TARGET) << 1)); + /* For gdb disassembler, maintain odd address. */ + if (info->flavour == bfd_target_unknown_flavour) info->target |= 1; (*info->print_address_func) (info->target, info); break; @@ -2658,6 +2657,12 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) infprintf (is, "0x%x", msbd + 1); break; + case 'i': + info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff) + | (GET_OP (insn, TARGET) << 2)); + (*info->print_address_func) (info->target, info); + break; + case 'j': /* 9-bit signed offset in bit 0. */ delta = GET_OP_S (insn, EVAOFFSET); infprintf (is, "%d", delta); diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c index 72f5842cc53..6d709ee5a32 100644 --- a/opcodes/mips-opc.c +++ b/opcodes/mips-opc.c @@ -852,7 +852,7 @@ const struct mips_opcode mips_builtin_opcodes[] = assembler, but will never match user input (because the line above will match first). */ {"jal", "a", 0x0c000000, 0xfc000000, UBD|WR_31, 0, I1 }, -{"jalx", "a", 0x74000000, 0xfc000000, UBD|WR_31, 0, I1 }, +{"jalx", "+i", 0x74000000, 0xfc000000, UBD|WR_31, 0, I1 }, {"la", "t,A(b)", 0, (int) M_LA_AB, INSN_MACRO, 0, I1 }, {"laa", "d,(b),t", 0x7000049f, 0xfc0007ff, LDD|SM|WR_d|RD_t|RD_b, 0, IOCT2 }, {"laad", "d,(b),t", 0x700004df, 0xfc0007ff, LDD|SM|WR_d|RD_t|RD_b, 0, IOCT2 }, diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c index 01cbcde489a..d90c7f3d4b6 100644 --- a/opcodes/mips16-opc.c +++ b/opcodes/mips16-opc.c @@ -167,7 +167,7 @@ const struct mips_opcode mips16_opcodes[] = {"jal", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, {"jal", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, {"jal", "a", 0x1800, 0xfc00, UBD|WR_31, 0, I1 }, -{"jalx", "a", 0x1c00, 0xfc00, UBD|WR_31, 0, I1 }, +{"jalx", "i", 0x1c00, 0xfc00, UBD|WR_31, 0, I1 }, {"jr", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1 }, {"jr", "R", 0xe820, 0xffff, UBD|RD_31, 0, I1 }, {"j", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1 }, -- 2.30.2