This is basic shifts for MVE. There are many shifts in MVE, but the ones handled here are:
- VSHL (imm)
- VSHRu (imm)
- VSHRs (imm)
- VSHL (vector)
- VSHL (register)
MVE, like NEON before it, doesn't have shift right by a vector (or register). We instead have to negate the amount and shift in the opposite direction. This means we have to convert any SHR's into a from of SHL (that is still signed or unsigned) with a negated condition and selecting from there. MVE still does have shifting by an immediate for SHL, ASR and LSR.
I've added lowering for these and for register forms, which work well for shift lefts but may require an extra fold of neg(vdup(x)) -> vdup(neg(x)) to optimally for right shifts.