]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
RISC-V: map zext.h to pack/packw if Zbkb is enabled
authorHau Hsu <hau.hsu@sifive.com>
Tue, 6 Aug 2024 03:56:18 +0000 (11:56 +0800)
committerNelson Chu <nelson@rivosinc.com>
Tue, 6 Aug 2024 08:07:27 +0000 (16:07 +0800)
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 [new file with mode: 0644]
gas/testsuite/gas/riscv/zext-to-pack.s [new file with mode: 0644]
gas/testsuite/gas/riscv/zext-to-packw-encoding.d [new file with mode: 0644]
opcodes/riscv-opc.c

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 (file)
index 0000000..86fcbce
--- /dev/null
@@ -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[     ]+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 (file)
index 0000000..bb2be3d
--- /dev/null
@@ -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 (file)
index 0000000..04e21e7
--- /dev/null
@@ -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[     ]+zext.h[       ]+a0,a0
index 8addcd0d4f79f7971bafc420b5125ca0949402c0..c4b089d5a175545227ac98fa4dda49e421b3ec62 100644 (file)
@@ -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 },