Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for RISC-V Zbb (Bit manipulation) extension #204

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

aman4150
Copy link
Collaborator

No description provided.

Note, we are introducing new instructions in our amd64 assembler,
because it makes the compiled code small, or well, sometimes it is necessary.

Signed-off-by: Aman <[email protected]>
Now that we support 64-bit execution mode in the polkavm, let's also
extend our implementation of Zbb instruction set in both interpreter and
compiler to support execution of these new instructions in 64-bit mode.

Signed-off-by: Aman <[email protected]>
@@ -1282,6 +1295,21 @@ pub mod inst {
None,
(fmt.write_fmt(core::format_args!("mov {}, {}", self.1.name_from(self.0), self.2.name_from(self.0)))),

movsx_8_to_64(Reg, Reg) =>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add this and the rest of new instructions to the tests like you did for rol?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, not sure how I missed these.

Comment on lines +1576 to +1577
[I_64, I_32] rotate_left = 152,
[I_64, I_32] rotate_left_word = 153,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is one supposed to be 32-bit and the other 64-bit? If so why they're both enabled on both 64-bit and 32-bit? The 32-bit shouldn't need the 64-bit one, right?

Also, to keep with the current convention, when there are 32-bit and 64-bit variants of the same instruction could you rename them so that one ends with _32 and the other with _64?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, rotate_left and rotate_left_word are available on both 32-bit and 64-bit.

The rotate_left_word is same as rotate_left on 32-bit, but on 64-bit it yield a sign-extended result.

Comment on lines +4063 to +4069
Self::RotateLeft => {
if rv64 {
cast((lhs as u64).rotate_left(rhs as u32)).to_signed()
} else {
cast((lhs as u32).rotate_left(rhs as u32) as i32).to_i64_sign_extend()
}
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so for this instruction specifically I would want to see a separate variant (instead of the rv64 flag) like it is for e.g. addition where you have a dedicated "32 bit + sign extend" variant. Otherwise anywhere else you will want to do any optimizations on these operations you'll have to remember to have this extra if and if you forget it'll be a bug; having this as an extra variant will remove this potential footgutn

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, there is no reason for actually doing sign extension here, I guess I simply copied the statement from above and replaced it with to_i64_sign_extend.

On 32-bit, it will get truncated again, so sign-extending or not, it's the same story.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose, I can still split the this operation type, but this does seem a bit redundant. Because anywhere we don't extend the result type to match the return value, code would not compile.

I will however, replace to_i64_sign_extend with a simply cast with zero-extend op.

cast((lhs as u32).rotate_left(rhs as u32) as i32).to_i64_sign_extend()
}
},
Self::RotateLeftWord => cast((lhs as u32).rotate_left(rhs as u32) as i32).to_i64_sign_extend(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this one to RotateLeft32AndSignExtend?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we could, but then it conflicts with our convention of using 32 and 64 in the operation kind name.

I suppose, I could rename is to RotateLeftWordSignExtend .

(O::RotateLeft, lhs, C(0)) => lhs,
(O::RotateLeft, C(0), _) => C(0),

(O::RotateLeftWord, lhs, C(0)) => lhs,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this incorrect? :P

(This will truncate the lhs and sign extend it to 64-bit instead of being a nop, no? See, that's the reason I was explicit about 32/64 and 32AndSignExtend everywhere. :P)

Copy link
Collaborator Author

@aman4150 aman4150 Nov 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will truncate the lhs and sign extend it to 64-bit instead of being a nop

And that is right thing to do.

RotateLeftWord is not a 32-bit only instruction, this is what the spec says:

let rs1 = EXTZ(X(rs1)[31..0])
let shamt = X(rs2)[4..0];
let result = (rs1 << shamt) | (rs1 >> (32 - shamt));
X(rd) = EXTS(result[31..0]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants