Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does MSIL have ROL and ROR instructions?

Tags:

c#

clr

cil

I wrote an Int128 type and it works great. I thought I could improve on its performance with a simple idea: Improve the shift operations which are a bit clumsy.

Because they are heavily used in multiplication and division, an improvement would have a ripple effect. So I began creating a dynamic method (to shift low and rotate high), only to discover that there are no OpCodes.Rol or OpCodes.Ror instructions.

Is this possible in IL?

like image 541
Tergiver Avatar asked Jul 10 '10 19:07

Tergiver


2 Answers

No.

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));
like image 190
codekaizen Avatar answered Oct 30 '22 21:10

codekaizen


To partially answer this question 7 years later, in case someone should need it.

You can use ROR/ROL in .Net.

MSIL doesn't directly contain ROR or ROL operations, but there are patterns that will make the JIT compiler generate ROR and ROL. RuyJIT (.Net and .Net core) supports this.

The details of improving .Net Core to use this pattern was 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 extending by same pattern to ROL:

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

To do this on 128-bit integer you can process as two 64-bit, then AND to extract "carry", AND to clear destination and OR to apply. This has to be mirrored in both directions (low->high and high->low). I'm not goin to bother with an example since this question is a bit old.

like image 39
Tedd Hansen Avatar answered Oct 30 '22 21:10

Tedd Hansen