##fixnum-add, ##fixnum-sub instructions open-code overflow check

db4
Slava Pestov 2008-11-28 05:33:58 -06:00
parent 6320b936ff
commit 5634becda1
12 changed files with 87 additions and 9 deletions

View File

@ -18,6 +18,7 @@ M: ##string-nth defs-vregs dst/tmp-vregs ;
M: ##compare defs-vregs dst/tmp-vregs ;
M: ##compare-imm defs-vregs dst/tmp-vregs ;
M: ##compare-float defs-vregs dst/tmp-vregs ;
M: ##fixnum-overflow defs-vregs temp>> 1array ;
M: insn defs-vregs drop f ;
M: ##unary uses-vregs src>> 1array ;
@ -34,6 +35,7 @@ M: ##compare-imm-branch uses-vregs src1>> 1array ;
M: ##dispatch uses-vregs src>> 1array ;
M: ##alien-getter uses-vregs src>> 1array ;
M: ##alien-setter uses-vregs [ src>> ] [ value>> ] bi 2array ;
M: ##fixnum-overflow uses-vregs [ src1>> ] [ src2>> ] bi 2array ;
M: _conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ;
M: _compare-imm-branch uses-vregs src1>> 1array ;
M: insn uses-vregs drop f ;
@ -43,6 +45,7 @@ UNION: vreg-insn
##write-barrier
##dispatch
##effect
##fixnum-overflow
##conditional-branch
##compare-imm-branch
_conditional-branch

View File

@ -92,6 +92,12 @@ INSN: ##shr-imm < ##binary-imm ;
INSN: ##sar-imm < ##binary-imm ;
INSN: ##not < ##unary ;
! Overflowing arithmetic
TUPLE: ##fixnum-overflow < insn src1 src2 temp ;
INSN: ##fixnum-add < ##fixnum-overflow ;
INSN: ##fixnum-sub < ##fixnum-overflow ;
INSN: ##fixnum-mul < ##fixnum-overflow ;
: ##tag-fixnum ( dst src -- ) tag-bits get ##shl-imm ; inline
: ##untag-fixnum ( dst src -- ) tag-bits get ##sar-imm ; inline

View File

@ -64,3 +64,6 @@ IN: compiler.cfg.intrinsics.fixnum
: emit-fixnum>bignum ( -- )
ds-pop ^^untag-fixnum ^^integer>bignum ds-push ;
: emit-fixnum-overflow-op ( quot -- )
[ 2inputs i 1 ##inc-d ] dip call begin-basic-block ; inline

View File

@ -22,6 +22,8 @@ IN: compiler.cfg.intrinsics
{
kernel.private:tag
math.private:fixnum+
math.private:fixnum-
math.private:fixnum+fast
math.private:fixnum-fast
math.private:fixnum-bitand
@ -88,6 +90,9 @@ IN: compiler.cfg.intrinsics
: emit-intrinsic ( node word -- )
{
{ \ kernel.private:tag [ drop emit-tag ] }
{ \ math.private:fixnum+ [ drop [ ##fixnum-add ] emit-fixnum-overflow-op ] }
{ \ math.private:fixnum- [ drop [ ##fixnum-sub ] emit-fixnum-overflow-op ] }
{ \ math.private:fixnum* [ drop [ ##fixnum-mul ] emit-fixnum-overflow-op ] }
{ \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op ] }
{ \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op ] }
{ \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op ] }

View File

@ -34,6 +34,9 @@ M: insn compute-stack-frame*
\ _gc t frame-required? set-word-prop
\ _spill t frame-required? set-word-prop
\ ##fixnum-add t frame-required? set-word-prop
\ ##fixnum-sub t frame-required? set-word-prop
\ ##fixnum-mul t frame-required? set-word-prop
: compute-stack-frame ( insns -- )
frame-required? off

View File

@ -62,4 +62,8 @@ M: ##compare-imm-branch propagate
M: ##dispatch propagate
[ resolve ] change-src ;
M: ##fixnum-overflow propagate
[ resolve ] change-src1
[ resolve ] change-src2 ;
M: insn propagate ;

View File

@ -156,6 +156,15 @@ M: ##shr-imm generate-insn dst/src1/src2 %shr-imm ;
M: ##sar-imm generate-insn dst/src1/src2 %sar-imm ;
M: ##not generate-insn dst/src %not ;
: src1/src2/temp ( insn -- src1 src2 temp )
[ src1>> register ]
[ src2>> register ]
[ temp>> register ] tri ; inline
M: ##fixnum-add generate-insn src1/src2/temp %fixnum-add ;
M: ##fixnum-sub generate-insn src1/src2/temp %fixnum-sub ;
M: ##fixnum-mul generate-insn src1/src2/temp %fixnum-mul ;
: dst/src/temp ( insn -- dst src temp )
[ dst/src ] [ temp>> register ] bi ; inline

View File

@ -77,6 +77,10 @@ HOOK: %shr-imm cpu ( dst src1 src2 -- )
HOOK: %sar-imm cpu ( dst src1 src2 -- )
HOOK: %not cpu ( dst src -- )
HOOK: %fixnum-add cpu ( src1 src2 temp -- )
HOOK: %fixnum-sub cpu ( src1 src2 temp -- )
HOOK: %fixnum-mul cpu ( src1 src2 temp -- )
HOOK: %integer>bignum cpu ( dst src temp -- )
HOOK: %bignum>integer cpu ( dst src temp -- )

View File

@ -23,8 +23,8 @@ M: x86.32 machine-registers
M: x86.32 ds-reg ESI ;
M: x86.32 rs-reg EDI ;
M: x86.32 stack-reg ESP ;
M: x86.32 temp-reg-1 EAX ;
M: x86.32 temp-reg-2 ECX ;
M: x86.32 temp-reg-1 ECX ;
M: x86.32 temp-reg-2 EDX ;
M:: x86.32 %dispatch ( src temp offset -- )
! Load jump table base.
@ -38,6 +38,10 @@ M:: x86.32 %dispatch ( src temp offset -- )
[ align-code ]
bi ;
! Registers for fastcall
M: x86.32 param-reg-1 drop EAX ;
M: x86.32 param-reg-2 drop EDX ;
M: x86.32 reserved-area-size 0 ;
M: x86.32 %alien-global 0 [] MOV rc-absolute-cell rel-dlsym ;

View File

@ -21,8 +21,8 @@ M: x86.64 machine-registers
M: x86.64 ds-reg R14 ;
M: x86.64 rs-reg R15 ;
M: x86.64 stack-reg RSP ;
M: x86.64 temp-reg-1 RAX ;
M: x86.64 temp-reg-2 RCX ;
M: x86.64 temp-reg-1 R8 ;
M: x86.64 temp-reg-2 R9 ;
M:: x86.64 %dispatch ( src temp offset -- )
! Load jump table base.
@ -37,8 +37,8 @@ M:: x86.64 %dispatch ( src temp offset -- )
[ align-code ]
bi ;
: param-reg-1 int-regs param-regs first ; inline
: param-reg-2 int-regs param-regs second ; inline
M: x86.64 param-reg-1 int-regs param-regs first ;
M: x86.64 param-reg-2 int-regs param-regs second ;
: param-reg-3 int-regs param-regs third ; inline
M: int-regs return-reg drop RAX ;

View File

@ -14,6 +14,9 @@ M: x86 two-operand? t ;
HOOK: temp-reg-1 cpu ( -- reg )
HOOK: temp-reg-2 cpu ( -- reg )
HOOK: param-reg-1 cpu ( -- reg )
HOOK: param-reg-2 cpu ( -- reg )
M: x86 %load-immediate MOV ;
M: x86 %load-indirect swap 0 MOV rc-absolute-cell rel-immediate ;
@ -90,6 +93,38 @@ M: x86 %shr-imm nip SHR ;
M: x86 %sar-imm nip SAR ;
M: x86 %not drop NOT ;
: ?MOV ( dst src -- )
2dup = [ 2drop ] [ MOV ] if ; inline
:: move>args ( src1 src2 -- )
{
{ [ src1 param-reg-2 = ] [ param-reg-1 src2 ?MOV param-reg-1 param-reg-2 XCHG ] }
{ [ src1 param-reg-1 = ] [ param-reg-2 src2 ?MOV ] }
{ [ src2 param-reg-1 = ] [ param-reg-2 src1 ?MOV param-reg-1 param-reg-2 XCHG ] }
{ [ src2 param-reg-2 = ] [ param-reg-1 src1 ?MOV ] }
[
param-reg-1 src1 MOV
param-reg-2 src2 MOV
]
} cond ;
:: overflow-template ( src1 src2 temp insn func -- )
<label> "end" set
temp src1 MOV
temp src2 insn call
ds-reg [] temp MOV
"end" get JNO
src1 src2 move>args
%prepare-alien-invoke
func f %alien-invoke
"end" resolve-label ;
M: x86 %fixnum-add ( src1 src2 temp -- )
[ ADD ] "overflow_fixnum_add" overflow-template ;
M: x86 %fixnum-sub ( src1 src2 temp -- )
[ SUB ] "overflow_fixnum_subtract" overflow-template ;
: bignum@ ( reg n -- op )
cells bignum tag-number - [+] ; inline
@ -158,9 +193,6 @@ M: x86 %div-float nip DIVSD ;
M: x86 %integer>float CVTSI2SD ;
M: x86 %float>integer CVTTSD2SI ;
: ?MOV ( dst src -- )
2dup = [ 2drop ] [ MOV ] if ; inline
M: x86 %copy ( dst src -- ) ?MOV ;
M: x86 %copy-float ( dst src -- )

View File

@ -12,6 +12,11 @@ void primitive_float_to_fixnum(void);
void primitive_fixnum_add(void);
void primitive_fixnum_subtract(void);
void primitive_fixnum_multiply(void);
DLLEXPORT F_FASTCALL void overflow_fixnum_add(F_FIXNUM x, F_FIXNUM y);
DLLEXPORT F_FASTCALL void overflow_fixnum_subtract(F_FIXNUM x, F_FIXNUM y);
DLLEXPORT F_FASTCALL void overflow_fixnum_multiply(F_FIXNUM x, F_FIXNUM y);
void primitive_fixnum_divint(void);
void primitive_fixnum_divmod(void);
void primitive_fixnum_shift(void);