Ok, if not ash-left-modfx then mask-signed-field because after correcting the wrong type declaration in your portable/fast way, it compiles to worse code - IMUL instead of a LEA to shift by 2, and a test for fixnum overflow.

(disassemble '(lambda (value position) ; works
                (declare (type type-number value) (type (integer 0 24) position))
                (let ((x (ash value position)))
                  (logior x (- (mask-field (byte 1 sb-vm:n-fixnum-bits) x))))))

; 125257AE:       C1F802           SAR EAX, 2                 ; no-arg-parsing entry point
;       B1:       8BCF             MOV ECX, EDI
;       B3:       C1F902           SAR ECX, 2
;       B6:       D3E0             SHL EAX, CL
;       B8:       6BD004           IMUL EDX, EAX, 4
;       BB:       7107             JNO L0
;       BD:       8BD0             MOV EDX, EAX
;       BF:       E81CAEADF1       CALL #x40005E0             ; ALLOC-SIGNED-BIGNUM-IN-EDX

(disassemble '(lambda (value position) ; works better
                (declare (type type-number value) (type (integer 0 24) position))
                (mask-signed-field 30 (ash value position))))

; 1255107E:       8BCF             MOV ECX, EDI               ; no-arg-parsing entry point
;       80:       C1F902           SAR ECX, 2
;       83:       8BD0             MOV EDX, EAX
;       85:       D3E2             SHL EDX, CL
;       87:       8BE5             MOV ESP, EBP

The latter is not usable only for not having compiled cross-modular early enough.
And since the expression using mask-signed-field is *exactly* the same as the 'fixnum' case of ash-left-modfx, I am unconvinced of the need to reinvent that wheel.
x86 lacks vops for mask-signed-field and ash-left-modfx but the generated code is perfectly fine.



On Sun, Mar 16, 2014 at 11:55 PM, Stas Boukarev <stassats@gmail.com> wrote:
Douglas Katzman <dougk@google.com> writes:

> I think the right thing is to define 'ash-left-modfx' for all targets, and
> have 'cross-modular' moved up in 'build-order.lisp-expr' so that for both
> host and target the expression can be (ash-left-modfx val shift)
>
> I've got some tools to help ensure that playing leapfrog/musical-chairs
> with files in a build order list doesn't mess things up in terms of an
> inline function that used to work but now it doesn't because it wasn't
> defined until after it was first called etc.  I'd feel much more
> comfortable rearranging things once I give that utility a crack at the SBCL
> sources. Unless somebody is willing to say sure, just move cross-modular
> earlier, and also remove the reader conditionals from numbers.lisp

There is really no reason to ever call ash-left-modfx, and if you call
it on a platform which doesn't implement it as a VOP, then it will be
slow as hell.

--
With best regards, Stas.