LoongArch: support disassembling certain pseudo-instructions
authorWANG Xuerui <git@xen0n.name>
Thu, 29 Jun 2023 16:34:58 +0000 (00:34 +0800)
committerliuzhensong <liuzhensong@loongson.cn>
Fri, 30 Jun 2023 02:17:56 +0000 (10:17 +0800)
commit17f9439038257b1de0c130a416a9a7645c653cb0
tree309c03231b447bcfbcf30868c54f7d3e3a15cc4f
parent69b9300e8789bd720994b2efc6e137139ee8055a
LoongArch: support disassembling certain pseudo-instructions

Add a flag in the pinfo field for being able to mark certain specialized
matchers as disassembler-only, so some degree of isolation between
assembler-side and disassembler-side can be achieved.

This isolation is necessary, firstly because some pseudo-instructions
cannot be fully described in the opcode table, like `li.[wd]`, so the
corresponding opcode entry cannot have meaningful match/mask values.
Secondly, some of these pseudo-instructions can be realized in more than
one plausible ways; e.g. `li.w rd, <something between 0 and 0x7ff>` can
be realized on LA64 with any of `addi.w`, `addi.d` or `ori`. If we tie
disassembly of such aliases with the corresponding GAS support, only one
canonical form among the above would be recognized as `li.w`, and it
would mildly impact the readability of disassembly output.
People wanting the exact disassembly can always set `-M no-aliases` to
get the original behavior back.

In addition, in certain cases, information is irreversibly lost after
assembling, so perfect round-trip would not be possible in such cases.
For example, `li.w` and `li.d` of immediates within int32_t range
produce the same code; in this patch, `addi.d rd, $zero, imm` is treated
as `li.d`, while `addi.w` and `ori` immediate loads are shown as `li.w`,
due to the expressible value range well within 32 bits.

gas/ChangeLog:

* config/tc-loongarch.c (get_loongarch_opcode): Ignore
disassembler-only aliases.
* testsuite/gas/loongarch/64_pcrel.d: Update test case.
* testsuite/gas/loongarch/imm_ins.d: Likewise.
* testsuite/gas/loongarch/imm_ins_32.d: Likewise.
* testsuite/gas/loongarch/jmp_op.d: Likewise.
* testsuite/gas/loongarch/li.d: Likewise.
* testsuite/gas/loongarch/macro_op.d: Likewise.
* testsuite/gas/loongarch/macro_op_32.d: Likewise.
* testsuite/gas/loongarch/macro_op_large_abs.d: Likewise.
* testsuite/gas/loongarch/macro_op_large_pc.d: Likewise.
* testsuite/gas/loongarch/nop.d: Likewise.
* testsuite/gas/loongarch/relax_align.d: Likewise.
* testsuite/gas/loongarch/reloc.d: Likewise.

include/ChangeLog:

* opcode/loongarch.h (INSN_DIS_ALIAS): Add.

ld/ChangeLog:

* testsuite/ld-loongarch-elf/jmp_op.d: Update test case.
* testsuite/ld-loongarch-elf/macro_op.d: Likewise.
* testsuite/ld-loongarch-elf/macro_op_32.d: Likewise.
* testsuite/ld-loongarch-elf/relax-align.dd: Likewise.

opcodes/ChangeLog:

* loongarch-dis.c: Move register name map declarations to top.
(get_loongarch_opcode_by_binfmt): Consider aliases when
disassembling without the no-aliases option.
(parse_loongarch_dis_option): Support the no-aliases option.
* loongarch-opc.c: Collect pseudo instructions into a new
dedicated table.

Signed-off-by: WANG Xuerui <git@xen0n.name>
20 files changed:
gas/config/tc-loongarch.c
gas/testsuite/gas/loongarch/64_pcrel.d
gas/testsuite/gas/loongarch/imm_ins.d
gas/testsuite/gas/loongarch/imm_ins_32.d
gas/testsuite/gas/loongarch/jmp_op.d
gas/testsuite/gas/loongarch/li.d
gas/testsuite/gas/loongarch/macro_op.d
gas/testsuite/gas/loongarch/macro_op_32.d
gas/testsuite/gas/loongarch/macro_op_large_abs.d
gas/testsuite/gas/loongarch/macro_op_large_pc.d
gas/testsuite/gas/loongarch/nop.d
gas/testsuite/gas/loongarch/relax_align.d
gas/testsuite/gas/loongarch/reloc.d
include/opcode/loongarch.h
ld/testsuite/ld-loongarch-elf/jmp_op.d
ld/testsuite/ld-loongarch-elf/macro_op.d
ld/testsuite/ld-loongarch-elf/macro_op_32.d
ld/testsuite/ld-loongarch-elf/relax-align.dd
opcodes/loongarch-dis.c
opcodes/loongarch-opc.c