When you shift a value on x86 with a variable shift count (in CL) the shift count is taken modulo the bit size of the destination operand. But is there an architecture which hasn't this kind of modulo-operation, i.e. if I shift further than there are bits in the operands the operand becomes zero (if I shift non-signed) ?
CodePudding user response:
x86-64 scalar shifts are mod-32 for 8 and 16-bit operand-size. Only 32 and 64-bit shifts are modulo the operand-size. (Modulo at all wasn't present in 8086, so being able to shift out all the bits in a 16-bit register was perhaps a relevant backwards-compat issue for 186. But for new extensions like 386 and amd64, there was no compat question so they could just define the semantics in a way that allowed a narrower barrel shifter with no extra condition.)
As Alex mentions, x86 SIMD shifts saturate the shift count, shifting out all the bits when >= element size. For example, pslld xmm0, xmm1
(And yes, they look at the full width of the low element of the source, not just the low byte.)
ARM uses all the bits in the low byte of the shift-count register for variable-count shifts. i.e. modulo reduced to 0..255, then saturated to 0..32. (Fun fact: for immediate shifts, it is possible to encode LSR by 1..32, but only LSL by 0..31)
IDK what other ISAs do; there might be some that are like x86 SIMD shifts.
CodePudding user response:
x86 has non-modulo shifts as well, if you consider MMX/SSE2/AVX2 psrlq
, psllw
, etc