I'm in favor of it meaning left shift, since that's what I've always thought it
was. I never make assumptions about what it does when shifting a negative
number to the right, but that's because I nearly always use it with nonnegative
numbers.
On Oct 30, 2020, 4:59 PM -0700, Taylor R Campbell
<campbell+mit-sch...@mumble.net>, wrote:
> What's (fix:lsh -123 -4) supposed to be?
>
> The obvious choices are -8, 4194296, or 18014398509481976, depending
> on whether it computes floor(-123/2^4) = -8 or whether it interprets
> -123 as a DATUM_LENGTH-bit string and shifts in zeros giving 4194296 =
> #x3ffff8 on 32-bit machines (26-bit fixnums) or 18014398509481976 =
> #x3ffffffffffff8 on 64-bit machines (58-bit fixnums).
>
> The name could be read as `logical shift', but the numerical semantics
> of logical right shifts depends on the size of a fixnum. The name
> could also be read as `left shift', since positive amounts are shifted
> left and negative amounts are shifted in the opposite direction.
>
> The history is a little complicated:
>
> - When gjr originally implemented the fixnum-lsh in 1990 (f4af6560),
> he implemented logical right shift semantics.
>
> - In some compiler back ends, gjr initially open-coded arithmetic
> right shift semantics, but later changed it to logical right shift.
>
> - When Arthur originally documented the fix:lsh procedure in 1991
> (bbc428a9), he documented arithmetic right shift semantics.
>
> - Two years later, Chris updated the documentation in 1993 (f7136490)
> to reflect what was actually implemented.
>
> - Over the next ten years or so, logical right shift semantics was
> also implemented in various compiler back ends.
>
> - In 2009, under the misapprehension that `lsh' meant `left shift' and
> not `logical shift' (https://savannah.gnu.org/bugs/?27385), I
> `fixed' the i386 and amd64 lap generation rules for fixnum-lsh so
> that it implemented arithmetic right shifts instead of logical right
> shifts (1f62f5c1).
>
> - ...Except I missed the case of a constant shift amount until a
> little under two years ago in a change I didn't actually commit
> until just recently (c689398c) while adding open-coding for
> integer-shift-left and integer-shift-right (which obviously has
> arithmetic right shift semantics since that's the only reasonable
> choice for arbitrary-size integers).
>
> So for most of the 30 years of the fix:lsh procedure and fixnum-lsh
> primitive, they have implemented logical right shifts. But several
> people were confused -- and in the ten years since I `broke' the
> semantics, apparently nobody has complained about having arithmetic
> right shifts on i386 and amd64.
>
> I'm not sure I've ever seen code that relies on logical right shift
> semantics in fix:lsh, and the semantics of such code would be
> unusually dependent on the size of a fixnum. And, to be honest, I'm
> kind of struggling to imagine why anyone would want logical right
> shift semantics for fixnums.
>
> What to do?
>
> 1. Forget we ever implemented logical right shifts and make it all
> arithmetic right shifts (which means, at this point, just changing
> the microcode primitive, really).
>
> 2. (a) Fix i386 and amd64 again to implement logical right shifts --
> and hope that doesn't break any code in the last decade!
> (b) Introduce a new primitive and rtl operator, say fixnum-ash,
> that does arithmetic shifts, and adapt the open-coding rules I
> just added for integer-shift-left and integer-shift-right to
> use it.
>
> 3. Something else?
>