From 87e720ad359ece678b37b036a61e0adcc60304f4 Mon Sep 17 00:00:00 2001 From: Hau Hsu Date: Tue, 6 Aug 2024 11:56:18 +0800 Subject: RISC-V: map zext.h to pack/packw if Zbkb is enabled The `zext.h` is zero-extend halfword instruction that belongs to Zbb. Currently `zext.h` falls back to 2 shifts if Zbb is not enabled. However, the encoding and operation is a special case of `pack/packw rd, rs1, rs2`, which belongs to Zbkb. The instructions pack the low halves of rs1 and rs2 into rd. When rs2 is zero (x0), they behave like zero-extend instruction, and the encoding are exactly the same as zext.h. Thus we can map `zext.h` to `pack` or `packw` (rv64) if Zbkb is enabled, instead of 2 shifts. This reduces one instruction. This patch does this by making `zext.h` also available for Zbkb. opcodes/ * riscv-opc.c (riscv_opcodes): Update `zext.h` entries to use `ZBB_OR_ZBKB` instruction class. gas/ * testsuite/gas/riscv/zext-to-pack.s: Add test for mapping zext to pack/packw encoding. * testsuite/gas/riscv/zext-to-pack-encoding.d: Likewise. * testsuite/gas/riscv/zext-to-packw-encoding.d: Likewise. --- gas/testsuite/gas/riscv/zext-to-pack-encoding.d | 11 +++++++++++ gas/testsuite/gas/riscv/zext-to-pack.s | 2 ++ gas/testsuite/gas/riscv/zext-to-packw-encoding.d | 11 +++++++++++ opcodes/riscv-opc.c | 4 ++-- 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/riscv/zext-to-pack-encoding.d create mode 100644 gas/testsuite/gas/riscv/zext-to-pack.s create mode 100644 gas/testsuite/gas/riscv/zext-to-packw-encoding.d diff --git a/gas/testsuite/gas/riscv/zext-to-pack-encoding.d b/gas/testsuite/gas/riscv/zext-to-pack-encoding.d new file mode 100644 index 0000000..86fcbce --- /dev/null +++ b/gas/testsuite/gas/riscv/zext-to-pack-encoding.d @@ -0,0 +1,11 @@ +#as: -march=rv32i_zbkb +#source: zext-to-pack.s +#objdump: -d + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+08054533[ ]+zext.h[ ]+a0,a0 diff --git a/gas/testsuite/gas/riscv/zext-to-pack.s b/gas/testsuite/gas/riscv/zext-to-pack.s new file mode 100644 index 0000000..bb2be3d --- /dev/null +++ b/gas/testsuite/gas/riscv/zext-to-pack.s @@ -0,0 +1,2 @@ +target: + zext.h a0, a0 diff --git a/gas/testsuite/gas/riscv/zext-to-packw-encoding.d b/gas/testsuite/gas/riscv/zext-to-packw-encoding.d new file mode 100644 index 0000000..04e21e7 --- /dev/null +++ b/gas/testsuite/gas/riscv/zext-to-packw-encoding.d @@ -0,0 +1,11 @@ +#as: -march=rv64i_zbkb +#source: zext-to-pack.s +#objdump: -d + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+0805453b[ ]+zext.h[ ]+a0,a0 diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 8addcd0..c4b089d 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -1228,8 +1228,8 @@ const struct riscv_opcode riscv_opcodes[] = {"sext.h", 0, INSN_CLASS_ZBB, "d,s", MATCH_SEXT_H, MASK_SEXT_H, match_opcode, 0 }, {"sext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_EXTH, NULL, INSN_MACRO }, {"zext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs,Cw", MATCH_C_ZEXT_H, MASK_C_ZEXT_H, match_opcode, INSN_ALIAS }, -{"zext.h", 32, INSN_CLASS_ZBB, "d,s", MATCH_PACK, MASK_PACK | MASK_RS2, match_opcode, 0 }, -{"zext.h", 64, INSN_CLASS_ZBB, "d,s", MATCH_PACKW, MASK_PACKW | MASK_RS2, match_opcode, 0 }, +{"zext.h", 32, INSN_CLASS_ZBB_OR_ZBKB, "d,s", MATCH_PACK, MASK_PACK | MASK_RS2, match_opcode, 0 }, +{"zext.h", 64, INSN_CLASS_ZBB_OR_ZBKB, "d,s", MATCH_PACKW, MASK_PACKW | MASK_RS2, match_opcode, 0 }, {"zext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_EXTH, NULL, INSN_MACRO }, {"orc.b", 0, INSN_CLASS_ZBB, "d,s", MATCH_GORCI | MATCH_SHAMT_ORC_B, MASK_GORCI | MASK_SHAMT, match_opcode, 0 }, {"clzw", 64, INSN_CLASS_ZBB, "d,s", MATCH_CLZW, MASK_CLZW, match_opcode, 0 }, -- cgit v1.1