rust-bitfield icon indicating copy to clipboard operation
rust-bitfield copied to clipboard

Feature request: Fields constructed of multiple ranges of bits

Open mumblingdrunkard opened this issue 1 year ago • 4 comments

I'm working on a RISC-V emulator and I use this crate to easily extract fields from RISC-V formatted instructions. It's pretty nifty. RISC-V instructions sometimes have values encoded inside of them that should be used in computations, called immediates. For some instruction formats, these immediates are split into parts to fit around other fields. E.g.:

image

Here, the immediate is split into two parts with the upper 7 bits in the range 31, 25 and the next 5 bits in the range 11, 7.

With the current implementation, I have these as separate fields imm_11_5 and imm_4_0 and I construct the immediate by a shift and bitwise OR.

It would be really nifty if I could specify fields that were composed of ranges of bits like:

imm, _: [(31, 25), (11, 7)];

Preferably with some syntax that doesn't break compatibility. I'm not very proficient with writing macros, but I could probably look to implement this myself if it's not something you can be bothered with.

If so, what should the syntax look like? I think the array of tuples looks pretty good, but I'm not sure if it would collide with some other syntax.

mumblingdrunkard avatar Dec 30 '23 14:12 mumblingdrunkard

In theory, this syntax should work.

I tried to implement it, but for some reason I don't understand rustc always want to match the rules for a single bit and doesn't want to match the rule I added that should match this syntax. I need to reread the macro documentation.

dzamlo avatar Dec 30 '23 19:12 dzamlo

I think the issue is that the part after the :is matched by $($exprs:expr),* in a previous rule and then the array become a single expression node in the AST and then when matching the next rule it's no more multiple tokens that can be matched independently.

I don't know how to change that.

dzamlo avatar Dec 30 '23 20:12 dzamlo

(As a side note, I also implemented a RISC-V emulator in rust: https://gitlab.com/dzamlo/emuriscv)

dzamlo avatar Dec 30 '23 21:12 dzamlo

I think it should be possible to simply use :

imm, _: 31, 25, 11, 7;

as a syntax, but I find that a bit confusing and error-prone.

dzamlo avatar Dec 30 '23 21:12 dzamlo