There's three basic shifts:
Intel has both sal
and shl
, but they map to the same opcode and most other architectures seem to only have three mnemonics in the first place.
You could recast the grid in terms of sign-preserving vs not:
But this gives rise to a new possibility, a left shift that is sign-preserving. This would have the behavior of retaining the sign bit, but shifting the rest as normal.
And now I have a couple questions:
Edit: To clarify, what I mean by "sign-preserving" is this, for the example of a left shift of 1 and a bit width of 8:
Not sign-preserving:
S A B C D E F G
/ / / / / / /
A B C D E F G 0
Sign-preserving:
S A B C D E F G
| / / / / / /
S B C D E F G 0
Hope this helps!
Footnote 1: Fun fact: x86 has a 2nd undocumented opcode for left shifts, e.g. d0 /4
and d0 /6
are both left-shift by 1 of a byte. Sandpile even claims that one is SHL and one is SAL, but the current Intel x86 manuals only document the /4
encoding for both SAL and SHL.
It's unclear if original 8086 was actually designed to use separate opcodes for the 2 names for the same operation, or if the alias opcode has always been undocumented. Whatever the history was, modern x86 no longer documents separate opcodes. (8 instructions share the same leading byte with the /r
field distinguishing them: ROL/ROR, RCL/RCR, SHL/SHR, and SAL/SAR. Sticking some other non-shift instruction into the /6
encoding would have cost transistors, and making it fault would probably also have cost more transistors, so it makes sense that original 8086 was designed with a redundant encoding for left shifting, the only question is if/how it was documented historically.)
But this is totally tangential to the actual question: x86's SAL is not the sign-bit-preserving shift being asked about.
No. The sign bit is not preserved -- as the sign bit will be shifted. And if the bit, just right of the sign bit is 1, then the resultant will be negative.
Arithmetic left shifts are equivalent to multiplication by a (positive, integral) power of the radix (e.g., a multiplication by a power of 2 for binary numbers). Logical left shifts are also equivalent, except multiplication and arithmetic shifts may trigger arithmetic overflow whereas logical shifts do not.
Many C compilers choose which right shift to perform depending on what type of integer is being shifted; often signed integers are shifted using the arithmetic shift, and unsigned integers are shifted using the logical shift.
Logical right shift means shifting the bits to the right and MSB(most significant bit) becomes 0. Example: Logical right shift of number 1 0 1 1 0 1 0 1 is 0 1 0 1 1 0 1 0. Arithmetic right shift means shifting the bits to the right and MSB(most significant bit) is same as in the original number.
The Intel 80960 shli instruction behaves this way. The description says, “if the bits shifted out are not the same as the sign bit, an overflow fault is generated. If overflow occurs, the sign of the result is the same as the sign of the src operand.” (The overflow fault can be masked. Even if it is not masked, the destination operand is written with the result.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With