##fixnum-add, ##fixnum-sub instructions open-code overflow check
parent
6320b936ff
commit
5634becda1
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ] }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 -- )
|
||||
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 -- )
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue