Use BSR instruction to implement fixnum-log2 intrinsic
parent
d2ce4355f8
commit
8a8f0c925c
|
@ -39,6 +39,7 @@ IN: compiler.cfg.hats
|
||||||
: ^^shr-imm ( src1 src2 -- dst ) ^^i2 ##shr-imm ; inline
|
: ^^shr-imm ( src1 src2 -- dst ) ^^i2 ##shr-imm ; inline
|
||||||
: ^^sar-imm ( src1 src2 -- dst ) ^^i2 ##sar-imm ; inline
|
: ^^sar-imm ( src1 src2 -- dst ) ^^i2 ##sar-imm ; inline
|
||||||
: ^^not ( src -- dst ) ^^i1 ##not ; inline
|
: ^^not ( src -- dst ) ^^i1 ##not ; inline
|
||||||
|
: ^^log2 ( src -- dst ) ^^i1 ##log2 ; inline
|
||||||
: ^^bignum>integer ( src -- dst ) ^^i1 i ##bignum>integer ; inline
|
: ^^bignum>integer ( src -- dst ) ^^i1 i ##bignum>integer ; inline
|
||||||
: ^^integer>bignum ( src -- dst ) ^^i1 i ##integer>bignum ; inline
|
: ^^integer>bignum ( src -- dst ) ^^i1 i ##integer>bignum ; inline
|
||||||
: ^^add-float ( src1 src2 -- dst ) ^^d2 ##add-float ; inline
|
: ^^add-float ( src1 src2 -- dst ) ^^d2 ##add-float ; inline
|
||||||
|
|
|
@ -92,6 +92,7 @@ INSN: ##shl-imm < ##binary-imm ;
|
||||||
INSN: ##shr-imm < ##binary-imm ;
|
INSN: ##shr-imm < ##binary-imm ;
|
||||||
INSN: ##sar-imm < ##binary-imm ;
|
INSN: ##sar-imm < ##binary-imm ;
|
||||||
INSN: ##not < ##unary ;
|
INSN: ##not < ##unary ;
|
||||||
|
INSN: ##log2 < ##unary ;
|
||||||
|
|
||||||
! Overflowing arithmetic
|
! Overflowing arithmetic
|
||||||
TUPLE: ##fixnum-overflow < insn src1 src2 ;
|
TUPLE: ##fixnum-overflow < insn src1 src2 ;
|
||||||
|
|
|
@ -53,6 +53,9 @@ IN: compiler.cfg.intrinsics.fixnum
|
||||||
: emit-fixnum-bitnot ( -- )
|
: emit-fixnum-bitnot ( -- )
|
||||||
ds-pop ^^not tag-mask get ^^xor-imm ds-push ;
|
ds-pop ^^not tag-mask get ^^xor-imm ds-push ;
|
||||||
|
|
||||||
|
: emit-fixnum-log2 ( -- )
|
||||||
|
ds-pop ^^log2 tag-bits get ^^sub-imm ^^tag-fixnum ds-push ;
|
||||||
|
|
||||||
: (emit-fixnum*fast) ( -- dst )
|
: (emit-fixnum*fast) ( -- dst )
|
||||||
2inputs ^^untag-fixnum ^^mul ;
|
2inputs ^^untag-fixnum ^^mul ;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ QUALIFIED: slots.private
|
||||||
QUALIFIED: strings.private
|
QUALIFIED: strings.private
|
||||||
QUALIFIED: classes.tuple.private
|
QUALIFIED: classes.tuple.private
|
||||||
QUALIFIED: math.private
|
QUALIFIED: math.private
|
||||||
|
QUALIFIED: math.integers.private
|
||||||
QUALIFIED: alien.accessors
|
QUALIFIED: alien.accessors
|
||||||
IN: compiler.cfg.intrinsics
|
IN: compiler.cfg.intrinsics
|
||||||
|
|
||||||
|
@ -93,6 +94,9 @@ IN: compiler.cfg.intrinsics
|
||||||
alien.accessors:set-alien-double
|
alien.accessors:set-alien-double
|
||||||
} [ t "intrinsic" set-word-prop ] each ;
|
} [ t "intrinsic" set-word-prop ] each ;
|
||||||
|
|
||||||
|
: enable-fixnum-log2 ( -- )
|
||||||
|
\ math.integers.private:fixnum-log2 t "intrinsic" set-word-prop ;
|
||||||
|
|
||||||
: emit-intrinsic ( node word -- node/f )
|
: emit-intrinsic ( node word -- node/f )
|
||||||
{
|
{
|
||||||
{ \ kernel.private:tag [ drop emit-tag iterate-next ] }
|
{ \ kernel.private:tag [ drop emit-tag iterate-next ] }
|
||||||
|
@ -108,6 +112,7 @@ IN: compiler.cfg.intrinsics
|
||||||
{ \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op iterate-next ] }
|
{ \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op iterate-next ] }
|
||||||
{ \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast iterate-next ] }
|
{ \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast iterate-next ] }
|
||||||
{ \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot iterate-next ] }
|
{ \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot iterate-next ] }
|
||||||
|
{ \ math.integers.private:fixnum-log2 [ drop emit-fixnum-log2 iterate-next ] }
|
||||||
{ \ math.private:fixnum*fast [ emit-fixnum*fast iterate-next ] }
|
{ \ math.private:fixnum*fast [ emit-fixnum*fast iterate-next ] }
|
||||||
{ \ math.private:fixnum< [ cc< emit-fixnum-comparison iterate-next ] }
|
{ \ math.private:fixnum< [ cc< emit-fixnum-comparison iterate-next ] }
|
||||||
{ \ math.private:fixnum<= [ cc<= emit-fixnum-comparison iterate-next ] }
|
{ \ math.private:fixnum<= [ cc<= emit-fixnum-comparison iterate-next ] }
|
||||||
|
|
|
@ -163,6 +163,7 @@ M: ##shl-imm generate-insn dst/src1/src2 %shl-imm ;
|
||||||
M: ##shr-imm generate-insn dst/src1/src2 %shr-imm ;
|
M: ##shr-imm generate-insn dst/src1/src2 %shr-imm ;
|
||||||
M: ##sar-imm generate-insn dst/src1/src2 %sar-imm ;
|
M: ##sar-imm generate-insn dst/src1/src2 %sar-imm ;
|
||||||
M: ##not generate-insn dst/src %not ;
|
M: ##not generate-insn dst/src %not ;
|
||||||
|
M: ##log2 generate-insn dst/src %log2 ;
|
||||||
|
|
||||||
: src1/src2 ( insn -- src1 src2 )
|
: src1/src2 ( insn -- src1 src2 )
|
||||||
[ src1>> register ] [ src2>> register ] bi ; inline
|
[ src1>> register ] [ src2>> register ] bi ; inline
|
||||||
|
|
|
@ -77,6 +77,7 @@ HOOK: %shl-imm cpu ( dst src1 src2 -- )
|
||||||
HOOK: %shr-imm cpu ( dst src1 src2 -- )
|
HOOK: %shr-imm cpu ( dst src1 src2 -- )
|
||||||
HOOK: %sar-imm cpu ( dst src1 src2 -- )
|
HOOK: %sar-imm cpu ( dst src1 src2 -- )
|
||||||
HOOK: %not cpu ( dst src -- )
|
HOOK: %not cpu ( dst src -- )
|
||||||
|
HOOK: %log2 cpu ( dst src -- )
|
||||||
|
|
||||||
HOOK: %fixnum-add cpu ( src1 src2 -- )
|
HOOK: %fixnum-add cpu ( src1 src2 -- )
|
||||||
HOOK: %fixnum-add-tail cpu ( src1 src2 -- )
|
HOOK: %fixnum-add-tail cpu ( src1 src2 -- )
|
||||||
|
|
|
@ -384,6 +384,8 @@ M: operand CMP OCT: 070 2-operand ;
|
||||||
|
|
||||||
: XCHG ( dst src -- ) OCT: 207 2-operand ;
|
: XCHG ( dst src -- ) OCT: 207 2-operand ;
|
||||||
|
|
||||||
|
: BSR ( dst src -- ) swap { HEX: 0f HEX: bd } (2-operand) ;
|
||||||
|
|
||||||
: NOT ( dst -- ) { BIN: 010 t HEX: f7 } 1-operand ;
|
: NOT ( dst -- ) { BIN: 010 t HEX: f7 } 1-operand ;
|
||||||
: NEG ( dst -- ) { BIN: 011 t HEX: f7 } 1-operand ;
|
: NEG ( dst -- ) { BIN: 011 t HEX: f7 } 1-operand ;
|
||||||
: MUL ( dst -- ) { BIN: 100 t HEX: f7 } 1-operand ;
|
: MUL ( dst -- ) { BIN: 100 t HEX: f7 } 1-operand ;
|
||||||
|
|
|
@ -5,10 +5,12 @@ cpu.x86.assembler cpu.x86.assembler.private cpu.architecture
|
||||||
kernel kernel.private math memory namespaces make sequences
|
kernel kernel.private math memory namespaces make sequences
|
||||||
words system layouts combinators math.order fry locals
|
words system layouts combinators math.order fry locals
|
||||||
compiler.constants compiler.cfg.registers
|
compiler.constants compiler.cfg.registers
|
||||||
compiler.cfg.instructions compiler.codegen
|
compiler.cfg.instructions compiler.cfg.intrinsics
|
||||||
compiler.codegen.fixup ;
|
compiler.codegen compiler.codegen.fixup ;
|
||||||
IN: cpu.x86
|
IN: cpu.x86
|
||||||
|
|
||||||
|
<< enable-fixnum-log2 >>
|
||||||
|
|
||||||
M: x86 two-operand? t ;
|
M: x86 two-operand? t ;
|
||||||
|
|
||||||
HOOK: temp-reg-1 cpu ( -- reg )
|
HOOK: temp-reg-1 cpu ( -- reg )
|
||||||
|
@ -92,6 +94,7 @@ M: x86 %shl-imm nip SHL ;
|
||||||
M: x86 %shr-imm nip SHR ;
|
M: x86 %shr-imm nip SHR ;
|
||||||
M: x86 %sar-imm nip SAR ;
|
M: x86 %sar-imm nip SAR ;
|
||||||
M: x86 %not drop NOT ;
|
M: x86 %not drop NOT ;
|
||||||
|
M: x86 %log2 BSR ;
|
||||||
|
|
||||||
: ?MOV ( dst src -- )
|
: ?MOV ( dst src -- )
|
||||||
2dup = [ 2drop ] [ MOV ] if ; inline
|
2dup = [ 2drop ] [ MOV ] if ; inline
|
||||||
|
|
|
@ -40,11 +40,13 @@ M: fixnum bitnot fixnum-bitnot ;
|
||||||
|
|
||||||
M: fixnum bit? neg shift 1 bitand 0 > ;
|
M: fixnum bit? neg shift 1 bitand 0 > ;
|
||||||
|
|
||||||
: (fixnum-log2) ( accum n -- accum )
|
: fixnum-log2 ( x -- n )
|
||||||
dup 1 number= [ drop ] [ [ 1+ ] [ 2/ ] bi* (fixnum-log2) ] if ;
|
0 swap [ dup 1 number= not ] [ [ 1+ ] [ 2/ ] bi* ] [ ] while drop ;
|
||||||
inline recursive
|
|
||||||
|
|
||||||
M: fixnum (log2) 0 swap (fixnum-log2) ;
|
M: fixnum (log2) fixnum-log2 ;
|
||||||
|
|
||||||
|
M: integer next-power-of-2
|
||||||
|
dup 2 <= [ drop 2 ] [ 1- log2 1+ 2^ ] if ;
|
||||||
|
|
||||||
M: bignum >fixnum bignum>fixnum ;
|
M: bignum >fixnum bignum>fixnum ;
|
||||||
M: bignum >bignum ;
|
M: bignum >bignum ;
|
||||||
|
|
|
@ -53,7 +53,7 @@ PRIVATE>
|
||||||
"log2 expects positive inputs" throw
|
"log2 expects positive inputs" throw
|
||||||
] [
|
] [
|
||||||
(log2)
|
(log2)
|
||||||
] if ; foldable
|
] if ; inline
|
||||||
|
|
||||||
: zero? ( x -- ? ) 0 number= ; inline
|
: zero? ( x -- ? ) 0 number= ; inline
|
||||||
: 1+ ( x -- y ) 1 + ; inline
|
: 1+ ( x -- y ) 1 + ; inline
|
||||||
|
@ -103,14 +103,9 @@ M: float fp-infinity? ( float -- ? )
|
||||||
drop f
|
drop f
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: (next-power-of-2) ( i n -- n )
|
GENERIC: next-power-of-2 ( m -- n ) foldable
|
||||||
2dup >= [
|
|
||||||
drop
|
|
||||||
] [
|
|
||||||
[ 1 shift ] dip (next-power-of-2)
|
|
||||||
] if ;
|
|
||||||
|
|
||||||
: next-power-of-2 ( m -- n ) 2 swap (next-power-of-2) ; foldable
|
M: real next-power-of-2 1+ >integer next-power-of-2 ;
|
||||||
|
|
||||||
: power-of-2? ( n -- ? )
|
: power-of-2? ( n -- ? )
|
||||||
dup 0 <= [ drop f ] [ dup 1- bitand zero? ] if ; foldable
|
dup 0 <= [ drop f ] [ dup 1- bitand zero? ] if ; foldable
|
||||||
|
|
Loading…
Reference in New Issue