Home > Net >  What does MSL do in the ARM instruction MOVI <Vd>.<T> #<imm8>, MSL #amount
What does MSL do in the ARM instruction MOVI <Vd>.<T> #<imm8>, MSL #amount

Time:07-19

I am confused about the operation MSL, which is used in a variant of the MOVI and MVNI instructions.

There's not a lot of information out there, but I have seen it referred to as "Masking Shift Left". Could anyone give an example of what a masking shift is? The instruction variant is also described as "shifting ones variant". I am not sure what this means either.

https://developer.arm.com/documentation/dui0801/c/A64-SIMD-Vector-Instructions/MOVI--vector-

CodePudding user response:

“Shifting ones” means that the bit positions where nothing is shifted to are set to 1. In a “logical shift”, or generally in a “shift” without explicit qualification, those bit positions are set to 0.

Demo (with 64-bit code):

#include <stdio.h>
int main() {
    unsigned long v0u, v0l, v1u, v1l, v2u, v2l;
    asm (
        "movi v0.4s, #42\n"
        "mov %[v0u], v0.d[0]\n"
        "mov %[v0l], v0.d[1]\n"
        "movi v1.4s, #42, lsl #8\n"
        "mov %[v1u], v1.d[0]\n"
        "mov %[v1l], v1.d[1]\n"
        "movi v2.4s, #42, msl #8\n"
        "mov %[v2u], v2.d[0]\n"
        "mov %[v2l], v2.d[1]\n"
        : [v0u] "=r" (v0u), [v0l] "=r" (v0l),
          [v1u] "=r" (v1u), [v1l] "=r" (v1l),
          [v2u] "=r" (v2u), [v2l] "=r" (v2l)
        :
        : "v0");
    printf("plain  : 6lx6lx\n", v0u, v0l);
    printf("lsl #8 : 6lx6lx\n", v1u, v1l);
    printf("msl #8 : 6lx6lx\n", v2u, v2l);
}

Output:

plain  : 0000002a0000002a0000002a0000002a
lsl #8 : 00002a0000002a0000002a0000002a00
msl #8 : 00002aff00002aff00002aff00002aff

I can't find this documented in the assembler manual. It is documented in the Architecture Reference Manual if you care to dig through it (references for version DDI0487H.a):

  • C7.2.204 MOVI p.2490: “shifting ones” is cmode == 110x.
  • AdvSIMDExpandImm p.11185: Zeros(X):imm8:Ones(8) where X is either 8 or 16.

CodePudding user response:

Running movi v0.4s, #32, msl #8 through gdb shows v0 containing {0x20FF, 0x20FF, 0x20FF, 0x20FF}, implying that MSL shifts to the left but pads in with 1's rather than 0's

In binary: 32 would be 00100000 shifting left 8 places padding in 1's gives 0010000011111111 which is 20FF in hex

The same is true with a negative immediate, with movi v1.4s #-32, msl #8 giving {0xE0FF, 0xE0FF, 0xE0FF, 0xE0FF}

  • Related