[PATCH] RISC-V: map zext.h to pack/packw if Zbkb is enabled

Hau Hsu hau.hsu@sifive.com
Fri Aug 2 03:28:16 GMT 2024


`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, and
moving `pack`, `packw` fowrard in the opcode table for disassemble.

opcode/
    * riscv-opc.c (riscv_opcodes): Move forward entries for `pack` and
      `packw` instructions. 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.
    * testsuite/gas/riscv/zext-to-pack.d: Likewise.
    * testsuite/gas/riscv/zext-to-packw.d: Likewise.
---
 gas/testsuite/gas/riscv/zext-to-pack.d  | 11 +++++++++++
 gas/testsuite/gas/riscv/zext-to-pack.s  |  2 ++
 gas/testsuite/gas/riscv/zext-to-packw.d | 11 +++++++++++
 opcodes/riscv-opc.c                     |  8 ++++----
 4 files changed, 28 insertions(+), 4 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/zext-to-pack.d
 create mode 100644 gas/testsuite/gas/riscv/zext-to-pack.s
 create mode 100644 gas/testsuite/gas/riscv/zext-to-packw.d

diff --git a/gas/testsuite/gas/riscv/zext-to-pack.d b/gas/testsuite/gas/riscv/zext-to-pack.d
new file mode 100644
index 00000000000..4745d004bad
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zext-to-pack.d
@@ -0,0 +1,11 @@
+#as: -march=rv32i_zbkb
+#source: zext-to-pack.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+08054533[ 	]+pack[ 	]+a0,a0,zero
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 00000000000..bb2be3dcaa6
--- /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.d b/gas/testsuite/gas/riscv/zext-to-packw.d
new file mode 100644
index 00000000000..295b1bd46c4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zext-to-packw.d
@@ -0,0 +1,11 @@
+#as: -march=rv64i_zbkb
+#source: zext-to-pack.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0805453b[ 	]+packw[ 	]+a0,a0,zero
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 14ec2903cdd..2cad0503533 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -1185,9 +1185,11 @@ const struct riscv_opcode riscv_opcodes[] =
 {"sext.h",     0, INSN_CLASS_ZCB_AND_ZBB,  "Cs,Cw", MATCH_C_SEXT_H, MASK_C_SEXT_H, match_opcode, INSN_ALIAS },
 {"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 },
+{"pack",       0, INSN_CLASS_ZBKB,  "d,s,t",    MATCH_PACK, MASK_PACK, match_opcode, 0 },
+{"packw",     64, INSN_CLASS_ZBKB,  "d,s,t",    MATCH_PACKW, MASK_PACKW, match_opcode, 0 },
 {"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 },
@@ -1197,9 +1199,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"brev8",     64, INSN_CLASS_ZBKB,  "d,s",      MATCH_GREVI | MATCH_SHAMT_BREV8, MASK_GREVI | MASK_SHAMT, match_opcode, 0 },
 {"zip",       32, INSN_CLASS_ZBKB,  "d,s",      MATCH_SHFLI|MATCH_SHAMT_ZIP_32, MASK_SHFLI|MASK_SHAMT, match_opcode, 0 },
 {"unzip",     32, INSN_CLASS_ZBKB,  "d,s",      MATCH_UNSHFLI|MATCH_SHAMT_ZIP_32, MASK_UNSHFLI|MASK_SHAMT, match_opcode, 0 },
-{"pack",       0, INSN_CLASS_ZBKB,  "d,s,t",    MATCH_PACK, MASK_PACK, match_opcode, 0 },
 {"packh",      0, INSN_CLASS_ZBKB,  "d,s,t",    MATCH_PACKH, MASK_PACKH, match_opcode, 0 },
-{"packw",     64, INSN_CLASS_ZBKB,  "d,s,t",    MATCH_PACKW, MASK_PACKW, match_opcode, 0 },
 {"andn",       0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_ANDN, MASK_ANDN, match_opcode, 0 },
 {"orn",        0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_ORN, MASK_ORN, match_opcode, 0 },
 {"xnor",       0, INSN_CLASS_ZBB_OR_ZBKB,  "d,s,t", MATCH_XNOR, MASK_XNOR, match_opcode, 0 },
-- 
2.39.3



More information about the Binutils mailing list