Does MSIL have ROL and ROR instructions?

I wrote an Int128 type and it works great. I thought I could improve my productivity with a simple idea: improve shift operations, which are a bit awkward.

Since they are heavily used in multiplication and division, the improvement will have a ripple effect. So I started creating a dynamic method (to move low and rotate high), only to discover that there are no OpCodes.Rol or OpCodes.Ror commands.

Is this possible in IL?

+4
source share
2 answers

Not.

You need to implement it with bit shifts

UInt64 highBits = 0; UInt64 lowBits = 1; Int32 n = 63; var altShift = (n - 63); var lowShiftedOff = (n - 63) > 0 ? 0 : (lowBits << n); var highShiftedOff = (n - 63) > 0 ? 0 : (highBits << n); var highResult = (UInt64)(highShiftedOff | (altShift > 0 ? (lowBits << altShift - 1) : 0)); var lowResult= (UInt64)(lowShiftedOff | (altShift > 0 ? (highBits << altShift - 1) : 0)); 
+4
source

Partially answer this question after 7 years, if someone needs it.

You can use ROR / ROL in .Net.

MSIL does not directly contain ROR or ROL operations, but there are patterns that will cause the JIT compiler to generate ROR and ROL. RuyJIT (.Net and .Net kernel) supports this.

Details of the .Net Core enhancement for using this template were discussed here and a month later .Net Core code was updated to use it .

Looking at the implementation of SHA512 , we find examples of ROR:

  public static UInt64 RotateRight(UInt64 x, int n) { return (((x) >> (n)) | ((x) << (64-(n)))); } 

And expands one pattern for ROL:

  public static UInt64 RotateLeft(UInt64 x, int n) { return (((x) << (n)) | ((x) >> (64-(n)))); } 

To do this on a 128-bit integer, you can process as two 64-bit, then AND to extract the β€œcarry”, AND to clear the destination, and OR to apply. This should be reflected in both directions (low β†’ high and high - low). I am not going to worry about the example because this question is a bit outdated.

+1
source

Source: https://habr.com/ru/post/1315291/


All Articles