in RV64, opcode overlap between bitmanip zext_h and scalar crypto pack
aamartin0000 opened this issue · comments
In RV64, the opcodes for zext_h and pack differ only in the rs2 field [24:20]. zext_h specifies this field as all zeros, but pack can specify any GPR, including x0. The problem is, the definition of pack when rs2=x0 is not the same as zext_h.
zext_h : X(rd) = EXTZ(X(rs1)[15..0]);
pack, RV64 with rs2=x0: X(rd) = EXTZ(X(rs1)[31..0]);
It kind of doesn't make sense to do pack when rs2=x0. I would recommend adding a restriction to the definitions of pack/packh/packw that the rs2 field can't be 00000 to resolve this conflict in the opcode space.
(packh and packw definitions do not have any functional conflict, but should get the same restriction, for consistency.)
Can I ask you what documentation / software you are looking?
I looked into GNU Binutils and it implements zext.h rd, rs
instruction as:
pack rd, rs1, x0
(on RV32)packw rd, rs1, x0
(on RV64)
Note that pack
and packw
only differs in the major opcode (OP
and OP-32
).
...and that matches the bit manipulation specification.
So on RV64,
zext_h : X(rd) = EXTZ(X(rs1)[15..0]);
packw, RV64 with rs2=x0: X(rd) = EXTS(X(x0)[15..0] || X(rs1)[15..0]) == EXTZ(X(rs1)[15..0]);
So unless the documentation / software you are looking has a bug, I don't see any issues in both scalar cryptography and bit manipulation specifications.
"pack" can be used in rv32 and rv64.
from the "official" opcodes:
riscv-opcodes/rv64_zbb: $pseudo_op rv64_zbe::packw zext.h rd rs1 31..25=0x04 24..20=0 14..12=0x4 6..2=0xE 1..0=0x3
riscv-opcodes/rv32_zbb: $pseudo_op rv_zbe::pack zext.h rd rs1 31..25=0x04 24..20=0 14..12=0x4 6..0=0x33
I was somewhat confused that zext.h could be 2 different opcodes. The definitions are consistent with, e.g. "add" vs "addw", and even "pack" vs "packw", but those have distinct mnemonics. So bottom line, there's no issue in the specs. Closing this issue.