Skip to content

riscv_gas_diag_unused_bits

Tsukasa OI edited this page Oct 28, 2022 · 4 revisions

GAS: Improve "bits undefined" diagnostics

Issue Solved (v2/v3)

After partial long instruction support up to 176-bit, it is found that it can break validate_riscv_insn function. In this version, it deals with the problem by ignoring instructions longer than 64-bits.

It also contains the same fix in v1.

Issue Solved (v1)

First ― just to experiment ― we change mask value of fcvt.d.s instruction from MASK_FCVT_D_S|MASK_RM to MASK_FCVT_D_S while not touching operands "D,S" and we run compiled assembler, we get following message:

Assembler messages:
Error: internal: bad RISC-V opcode (bits 0xffffffff00007000 undefined): fcvt.d.s D,S
Fatal error: internal: broken assembler.  No assembly attempted

Bits 0x7000 corresponds to rm (rounding mode) bits we just removed and no corresponding operands are found (making definition of fcvt.d.s instruction invalid).

Then, what about 0xffffffff00000000 (upper 32-bits)?

Yes, they are non-instruction bits. Because of ~ (bitwise complement) operator while computing undefined bits, it also displays non-instruction bits.

This commit changes how undefined/invalid bits are computed.

  • Before:
    ~(used & required)
  • After:
    (used ^ required)

After this patch, following error message is generated.

Assembler messages:
Error: internal: bad RISC-V opcode (bits 0x7000 undefined or invalid): fcvt.d.s D,S
Fatal error: internal: broken assembler.  No assembly attempted

Note that we are testing for "undefined or invalid" bits here, not just undefined bits. In fact, if we corrupt a variant of c.addi instruction with ADDITIONAL "j" operand (which is an immediate for I-type instruction, upper 12-bits of 32-bit instruction encoding), we get following message:

Assembler messages:
Error: internal: bad RISC-V opcode (bits 0xfff00000 undefined or invalid): addi d,CU,Cj,j
Fatal error: internal: broken assembler.  No assembly attempted

Okay, extra "j" operand generates extra bits (that should not have been defined considering its 16-bit encoding) and words "undefined or invalid" are working here. We are correctly capturing invalid extra bits. Before this patch, invalid bits are hidden by 0xffffffffffff0000 (48 non-instruction bits).

This patchset also resolves a possible portability problem where unsigned long long is larger than 64-bits.

Clone this wiki locally