summaryrefslogtreecommitdiff
path: root/opcodes/mips-dis.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@orcam.me.uk>2021-05-29 03:26:32 +0200
committerMaciej W. Rozycki <macro@orcam.me.uk>2021-05-29 03:26:32 +0200
commit9204ccd4b136e01457f6dfd2d62aaa98530ce740 (patch)
tree1e0bb744bfe15b40a4fc368be826232eae55ad85 /opcodes/mips-dis.c
parenta3fb396f2dc57f585a49091e12ec6c588c45e681 (diff)
downloadbinutils-gdb-9204ccd4b136e01457f6dfd2d62aaa98530ce740.tar.gz
MIPS/opcodes: Do not use CP0 register names for control registers
The CP0 control register set has never been defined, however encodings for the CFC0 and CTC0 instructions remained available for implementers up until the MIPS32 ISA declared them invalid and causing the Reserved Instruction exception[1]. Therefore we handle them for both assembly and disassembly, however in the latter case the names of CP0 registers from the regular set are incorrectly printed if named registers are requested. This is because we do not define separate operand classes for coprocessor regular and control registers respectively, which means the disassembler has no way to tell the two cases apart. Consequently nonsensical disassembly is produced like: cfc0 v0,c0_random Later the MIPSr5 ISA reused the encodings for XPA ASE MFHC0 and MTHC0 instructions[2] although it failed to document them in the relevant opcode table until MIPSr6 only. Correct the issue then by defining a new register class, OP_REG_CONTROL, and corresponding operand codes, `g' and `y' for the two positions in the machine instruction a control register operand can take. Adjust the test cases affected accordingly. While at it swap the regular MIPS opcode table "cfc0" and "ctc0" entries with each other so that they come in the alphabetical order. References: [1] "MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set", MIPS Technologies, Inc., Document Number: MD00086, Revision 1.00, August 29, 2002, Table A-9 "MIPS32 COP0 Encoding of rs Field", p. 242 [2] "MIPS Architecture For Programmers, Volume II-A: The MIPS32 Instruction Set", MIPS Technologies, Inc., Document Number: MD00086, Revision 5.04, December 11, 2013, Section 3.2 "Alphabetical List of Instructions", pp. 195, 216 include/ * opcode/mips.h: Document `g' and `y' operand codes. (mips_reg_operand_type): Add OP_REG_CONTROL enumeration constant. gas/ * tc-mips.c (convert_reg_type) <OP_REG_CONTROL>: New case. (macro) <M_TRUNCWS, M_TRUNCWD>: Use the `g' rather than `G' operand code. opcodes/ * mips-dis.c (print_reg) <OP_REG_COPRO>: Move control register handling code over to... <OP_REG_CONTROL>: ... this new case. * mips-opc.c (decode_mips_operand) <'g', 'y'>: New cases. (mips_builtin_opcodes): Update "cfc1", "ctc1", "cttc1", "cttc2", "cfc0", "ctc0", "cfc2", "ctc2", "cfc3", and "ctc3" entries replacing the `G' operand code with `g'. Update "cftc1" and "cftc2" entries replacing the `E' operand code with `y'. * micromips-opc.c (decode_micromips_operand) <'g'>: New case. (micromips_opcodes): Update "cfc1", "cfc2", "ctc1", and "ctc2" entries replacing the `G' operand code with `g'. binutils/ * testsuite/binutils-all/mips/mips-xpa-virt-1.d: Correct CFC0 operand disassembly. * testsuite/binutils-all/mips/mips-xpa-virt-3.d: Likewise.
Diffstat (limited to 'opcodes/mips-dis.c')
-rw-r--r--opcodes/mips-dis.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 0bdf7cf8b8d..75231ae0a83 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -1192,7 +1192,12 @@ print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
case OP_REG_COPRO:
if (opcode->name[strlen (opcode->name) - 1] == '0')
info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
- else if (opcode->name[strlen (opcode->name) - 1] == '1')
+ else
+ info->fprintf_func (info->stream, "$%d", regno);
+ break;
+
+ case OP_REG_CONTROL:
+ if (opcode->name[strlen (opcode->name) - 1] == '1')
info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
else
info->fprintf_func (info->stream, "$%d", regno);