x86
Factor documentation > Factor handbook > The implementation > System interface > Processor detection
Prev:arm


Vocabulary
system

Definition
IN: system

UNION: x86 x86.32 x86.64 ;


Methods
USING: combinators cpu.architecture cpu.x86.assembler system ;

M: x86 %abs-vector
{
{ char-16-rep [ PABSB ] }
{ short-8-rep [ PABSW ] }
{ int-4-rep [ PABSD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %abs-vector-reps
{ { ssse3? { char-16-rep short-8-rep int-4-rep } } }
available-reps ;


USING: cpu.architecture cpu.x86.assembler
cpu.x86.assembler.operands kernel system ;

M: x86 %add 2over eq? [ nip ADD ] [ [+] LEA ] if ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %add-float double-rep two-operand ADDSD ;


USING: cpu.architecture cpu.x86.assembler
cpu.x86.assembler.operands kernel system ;

M: x86 %add-imm 2over eq? [ nip ADD ] [ [+] LEA ] if ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %add-sub-vector
[ two-operand ] keep {
{ float-4-rep [ ADDSUBPS ] }
{ double-2-rep [ ADDSUBPD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %add-sub-vector-reps
{ { sse3? { float-4-rep double-2-rep } } } available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %add-vector
[ two-operand ] keep {
{ float-4-rep [ ADDPS ] }
{ double-2-rep [ ADDPD ] }
{ char-16-rep [ PADDB ] }
{ uchar-16-rep [ PADDB ] }
{ short-8-rep [ PADDW ] }
{ ushort-8-rep [ PADDW ] }
{ int-4-rep [ PADDD ] }
{ uint-4-rep [ PADDD ] }
{ longlong-2-rep [ PADDQ ] }
{ ulonglong-2-rep [ PADDQ ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %add-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: combinators compiler.cfg.instructions cpu.architecture
cpu.x86 kernel namespaces system ;

M: x86 %alien-assembly
[ gc-map set ( -- ) call-effect ] 2curry emit-alien-insn ;


USING: compiler.codegen.relocation compiler.constants
cpu.architecture cpu.x86.assembler kernel system ;

M: x86 %alien-global
[ 0 MOV ] 2dip rc-absolute-cell rel-dlsym ;


USING: compiler.codegen.gc-maps cpu.architecture cpu.x86
cpu.x86.assembler locals system ;

M:: x86 %alien-indirect
( src reg-inputs stack-inputs reg-outputs dead-outputs cleanup stack-size gc-map -- )
reg-inputs stack-inputs reg-outputs dead-outputs cleanup
stack-size
[ src ?spill-slot CALL gc-map gc-map-here ] emit-alien-insn
;


USING: cpu.architecture cpu.x86 kernel system ;

M: x86 %alien-invoke [ %c-invoke ] 3curry emit-alien-insn ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %alien-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 locals system ;

M:: x86 %allot ( dst size class nursery-ptr -- )
nursery-ptr dst load-allot-ptr dst class store-header
dst class store-tagged nursery-ptr size inc-allot-ptr ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %and int-rep two-operand AND ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %and-imm int-rep two-operand AND ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %and-vector
[ two-operand ] keep {
{ float-4-rep [ ANDPS ] }
{ double-2-rep [ ANDPS ] }
[ drop PAND ]
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %and-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %andn-vector
[ two-operand ] keep {
{ float-4-rep [ ANDNPS ] }
{ double-2-rep [ ANDNPS ] }
[ drop PANDN ]
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %andn-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %avg-vector
[ two-operand ] keep
{ { uchar-16-rep [ PAVGB ] } { ushort-8-rep [ PAVGW ] } }
case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %avg-vector-reps
{ { sse2? { uchar-16-rep ushort-8-rep } } } available-reps
;


USING: cpu.architecture cpu.x86.assembler system ;

M: x86 %bit-count POPCNT ;


USING: alien compiler.codegen.labels cpu.architecture cpu.x86
cpu.x86.assembler layouts locals namespaces system ;

M:: x86 %box-alien ( dst src temp -- )
[
"end" define-label dst \ f type-number MOV src src TEST
"end" get JE dst 5 cells alien temp %allot dst 1 alien@
\ f type-number MOV dst 2 alien@ \ f type-number MOV
dst 3 alien@ src MOV dst 4 alien@ src MOV
"end" resolve-label
] with-scope ;


USING: alien byte-arrays classes.algebra combinators
compiler.codegen.labels cpu.architecture cpu.x86
cpu.x86.assembler kernel layouts locals namespaces system ;

M:: x86 %box-displaced-alien
( dst displacement base temp base-class -- )
[
"end" define-label dst base MOV
displacement displacement TEST "end" get JE
dst 5 cells alien temp %allot dst 2 alien@
\ f type-number MOV dst displacement base temp {
{
[ base-class \ f class<= ]
[ 2drop %box-displaced-alien/f ]
}
{
[ base-class \ alien class<= ]
[ %box-displaced-alien/alien ]
}
{
[ base-class \ byte-array class<= ]
[ %box-displaced-alien/byte-array ]
}
[ %box-displaced-alien/dynamic ]
} cond "end" resolve-label
] with-scope ;


USING: compiler.codegen.relocation compiler.constants
cpu.architecture cpu.x86.assembler system ;

M: x86 %call 0 CALL rc-relative rel-word-pic ;


USING: compiler.codegen.gc-maps cpu.architecture memory system
;

M: x86 %call-gc \ minor-gc %call gc-map-here ;


USING: cpu.architecture cpu.x86 kernel sequences system ;

M: x86 %callback-inputs
[ [ first3 %load-reg-param ] each ]
[ [ first3 %load-stack-param ] each ] bi* %begin-callback ;


USING: cpu.architecture cpu.x86 sequences system ;

M: x86 %callback-outputs
%end-callback [ first3 %store-reg-param ] each ;


USING: combinators compiler.cfg.comparisons cpu.architecture
cpu.x86 cpu.x86.assembler cpu.x86.assembler.operands layouts
locals system ;

M:: x86 %check-nursery-branch
( label size cc temp1 temp2 -- )
temp1 load-zone-offset temp2 temp1 [] MOV temp2 size ADD
temp2 temp1 2 cells [+] CMP cc
{ { cc<= [ label JLE ] } { cc/<= [ label JG ] } } case ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %compare ( dst src1 src2 cc temp -- )
src1 src2 CMP dst cc temp %boolean ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %compare-branch ( label src1 src2 cc -- )
src1 src2 CMP label cc %branch ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %compare-float-ordered [ COMISD ] (%compare-float) ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %compare-float-ordered-branch
[ COMISD ] (%compare-float-branch) ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %compare-float-unordered [ UCOMISD ] (%compare-float) ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %compare-float-unordered-branch
[ UCOMISD ] (%compare-float-branch) ;


USING: cpu.architecture cpu.x86 locals system ;

M:: x86 %compare-imm ( dst src1 src2 cc temp -- )
src1 src2 (%compare-imm) dst cc temp %boolean ;


USING: cpu.architecture cpu.x86 locals system ;

M:: x86 %compare-imm-branch ( label src1 src2 cc -- )
src1 src2 (%compare-imm) label cc %branch ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %compare-integer-imm ( dst src1 src2 cc temp -- )
src1 src2 CMP dst cc temp %boolean ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %compare-integer-imm-branch
( label src1 src2 cc -- ) src1 src2 CMP label cc %branch ;


USING: cpu.architecture cpu.x86 cpu.x86.sse kernel system ;

M: x86 %compare-vector
[ [ two-operand ] keep ] dip over float-vector-rep?
[ %compare-float-vector ] [ %compare-int-vector ] if ;


USING: cpu.architecture cpu.x86.sse kernel system ;

M: x86 %compare-vector-ccs
swap float-vector-rep?
[ %compare-float-vector-ccs ] [ %compare-int-vector-ccs ]
if ;


USING: combinators compiler.cfg.comparisons cpu.architecture
cpu.x86.sse kernel sequences system ;

M: x86 %compare-vector-reps
{
{
[ dup { cc= cc/= cc/<>= cc<>= } member-eq? ]
[ drop %compare-vector-eq-reps ]
}
[ drop %compare-vector-ord-reps ]
} cond ;


USING: alien.c-types combinators cpu.architecture cpu.x86
kernel system ;

M: x86 %convert-integer
{
{ char [ 8 %sign-extend ] }
{ uchar [ 8 %zero-extend ] }
{ short [ 16 %sign-extend ] }
{ ushort [ 16 %zero-extend ] }
{ int [ 32 %sign-extend ] }
{ uint [ 32 [ 2drop ] (%convert-integer) ] }
} case ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler.operands
kernel system ;

M: x86 %copy
2over eq?
[ 3drop ] [
[ [ ?spill-slot ] bi@ ] dip 2over [ register? ] both?
[ copy-register* ] [ copy-memory* ] if
] if ;


USING: compiler.codegen.relocation compiler.constants
cpu.architecture cpu.x86.assembler cpu.x86.assembler.operands
kernel layouts locals make math namespaces sequences system ;

M:: x86 %dispatch ( src temp -- )
temp 4294967295 MOV
building get length :> start 0 rc-absolute-cell rel-here
temp src 127 [++] JMP
building get length :> end cell alignment
[ end start - + building get dup pop* push ]
[ (align-code) ] bi ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %div-float double-rep two-operand DIVSD ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %div-vector
[ two-operand ] keep
{ { float-4-rep [ DIVPS ] } { double-2-rep [ DIVPD ] } }
case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %div-vector-reps
{ { sse? { float-4-rep } } { sse2? { double-2-rep } } }
available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %dot-vector
[ two-operand ] keep {
{ float-4-rep [ 255 DPPS ] }
{ double-2-rep [ 255 DPPD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %dot-vector-reps
{ { sse4.1? { float-4-rep double-2-rep } } } available-reps
;


USING: cpu.architecture cpu.x86.assembler cpu.x86.sse kernel
system ;

M: x86 %double>single-float
[ %clear-unless-in-place ] [ CVTSD2SS ] 2bi ;


USING: cpu.architecture cpu.x86 layouts math system ;

M: x86 %epilogue cell - incr-stack-reg ;


USING: combinators cpu.architecture cpu.x86.assembler kernel
system ;

M: x86 %fill-vector
{
{ double-2-rep [ dup [ XORPS ] [ CMPEQPS ] 2bi ] }
{ float-4-rep [ dup [ XORPS ] [ CMPEQPS ] 2bi ] }
[ drop dup PCMPEQB ]
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %fill-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %fixnum-add [ ADD ] fixnum-overflow ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %fixnum-mul [ IMUL2 ] fixnum-overflow ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %fixnum-sub [ SUB ] fixnum-overflow ;


USING: cpu.architecture cpu.x86.assembler kernel system ;

M: x86 %float-pack-vector drop CVTPD2PS ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %float-pack-vector-reps
{ { sse2? { double-2-rep } } } available-reps ;


USING: cpu.architecture cpu.x86.assembler system ;

M: x86 %float>integer CVTTSD2SI ;


USING: combinators cpu.architecture cpu.x86.assembler system ;

M: x86 %float>integer-vector
{ { float-4-rep [ CVTTPS2DQ ] } } case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %float>integer-vector-reps
{ { sse2? { float-4-rep } } } available-reps ;


USING: cpu.architecture cpu.x86.assembler
cpu.x86.assembler.operands locals system ;

M:: x86 %gather-int-vector-4
( dst src1 src2 src3 src4 rep -- )
dst rep %zero-vector dst src1 32-bit-version-of 0 PINSRD
dst src2 32-bit-version-of 1 PINSRD
dst src3 32-bit-version-of 2 PINSRD
dst src4 32-bit-version-of 3 PINSRD ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %gather-int-vector-4-reps
{ { sse4.1? { int-4-rep uint-4-rep } } } available-reps ;


USING: combinators cpu.architecture cpu.x86.assembler locals
system ;

M:: x86 %gather-vector-2 ( dst src1 src2 rep -- )
rep signed-rep {
{
double-2-rep
[ dst src1 double-2-rep %copy dst src2 MOVLHPS ]
}
{
longlong-2-rep
[
dst src1 longlong-2-rep %copy
dst src2 PUNPCKLQDQ
]
}
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %gather-vector-2-reps
{
{
sse2?
{ double-2-rep longlong-2-rep ulonglong-2-rep }
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86.assembler locals
system ;

M:: x86 %gather-vector-4 ( dst src1 src2 src3 src4 rep -- )
rep signed-rep {
{
float-4-rep
[
dst src1 float-4-rep %copy dst src2 UNPCKLPS
src3 src4 UNPCKLPS dst src3 MOVLHPS
]
}
{
int-4-rep
[
dst src1 int-4-rep %copy dst src2 PUNPCKLDQ
src3 src4 PUNPCKLDQ dst src3 PUNPCKLQDQ
]
}
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %gather-vector-4-reps
{ { sse2? { float-4-rep int-4-rep uint-4-rep } } }
available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %horizontal-add-vector
[ two-operand ] keep signed-rep {
{ float-4-rep [ HADDPS ] }
{ double-2-rep [ HADDPD ] }
{ int-4-rep [ PHADDD ] }
{ short-8-rep [ PHADDW ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %horizontal-add-vector-reps
{
{ sse3? { float-4-rep double-2-rep } }
{
ssse3?
{ int-4-rep uint-4-rep short-8-rep ushort-8-rep }
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %horizontal-shl-vector-imm two-operand PSLLDQ ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %horizontal-shl-vector-imm-reps
{
{
sse2?
{
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
float-4-rep
double-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %horizontal-shr-vector-imm two-operand PSRLDQ ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %horizontal-shr-vector-imm-reps
{
{
sse2?
{
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
float-4-rep
double-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 system ;

M: x86 %inc-d ds-reg (%inc) ;


USING: cpu.architecture cpu.x86 system ;

M: x86 %inc-r rs-reg (%inc) ;


USING: cpu.architecture cpu.x86.assembler kernel system ;

M: x86 %integer>float [ drop dup XORPS ] [ CVTSI2SD ] 2bi ;


USING: combinators cpu.architecture cpu.x86.assembler system ;

M: x86 %integer>float-vector
{ { int-4-rep [ CVTDQ2PS ] } } case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %integer>float-vector-reps
{ { sse2? { int-4-rep } } } available-reps ;


USING: cpu.architecture cpu.x86.assembler kernel system ;

M: x86 %integer>scalar drop MOVD ;


USING: compiler.codegen.relocation compiler.constants
cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %jump
%prepare-jump 0 JMP rc-relative rel-word-pic-tail ;


USING: compiler.codegen.labels compiler.constants
cpu.architecture cpu.x86.assembler system ;

M: x86 %jump-label 0 JMP rc-relative label-fixup ;


USING: alien.c-types alien.data cpu.architecture system ;

M: x86 %load-double double <ref> double-rep %load-vector ;


USING: alien.c-types alien.data cpu.architecture system ;

M: x86 %load-float float <ref> float-rep %load-vector ;


USING: cpu.architecture cpu.x86.assembler kernel math system ;

M: x86 %load-immediate [ dup XOR ] [ MOV ] if-zero ;


USING: cpu.architecture cpu.x86 system ;

M: x86 %load-memory (%memory) (%load-memory) ;


USING: cpu.architecture cpu.x86 system ;

M: x86 %load-memory-imm (%memory-imm) (%load-memory) ;


USING: compiler.codegen.relocation compiler.constants
cpu.architecture cpu.x86.assembler kernel layouts system ;

M: x86 %load-reference
[ swap 0 MOV rc-absolute-cell rel-literal ]
[ \ f type-number MOV ] if* ;


USING: compiler.cfg.stack-frame cpu.architecture cpu.x86
cpu.x86.assembler locals system ;

M:: x86 %local-allot ( dst size align offset -- )
dst offset local-allot-offset special-offset stack@ LEA ;


USING: cpu.architecture cpu.x86.assembler system ;

M: x86 %log2 BSR ;


USING: compiler.codegen.relocation cpu.architecture
cpu.x86.assembler math system ;

M: x86 %loop-entry 16 alignment [ NOP ] times ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler kernel system
;

M: x86 %max int-rep two-operand [ CMP ] [ CMOVL ] 2bi ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %max-float double-rep two-operand MAXSD ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %max-vector
[ two-operand ] keep {
{ char-16-rep [ PMAXSB ] }
{ uchar-16-rep [ PMAXUB ] }
{ short-8-rep [ PMAXSW ] }
{ ushort-8-rep [ PMAXUW ] }
{ int-4-rep [ PMAXSD ] }
{ uint-4-rep [ PMAXUD ] }
{ float-4-rep [ MAXPS ] }
{ double-2-rep [ MAXPD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %max-vector-reps
{
{ sse? { float-4-rep } }
{ sse2? { uchar-16-rep short-8-rep double-2-rep } }
{
sse4.1?
{ char-16-rep ushort-8-rep int-4-rep uint-4-rep }
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %merge-vector-head
[ two-operand ] keep signed-rep {
{ double-2-rep [ MOVLHPS ] }
{ float-4-rep [ UNPCKLPS ] }
{ longlong-2-rep [ PUNPCKLQDQ ] }
{ int-4-rep [ PUNPCKLDQ ] }
{ short-8-rep [ PUNPCKLWD ] }
{ char-16-rep [ PUNPCKLBW ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %merge-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %merge-vector-tail
[ two-operand ] keep signed-rep {
{ double-2-rep [ UNPCKHPD ] }
{ float-4-rep [ UNPCKHPS ] }
{ longlong-2-rep [ PUNPCKHQDQ ] }
{ int-4-rep [ PUNPCKHDQ ] }
{ short-8-rep [ PUNPCKHWD ] }
{ char-16-rep [ PUNPCKHBW ] }
} case ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler kernel system
;

M: x86 %min int-rep two-operand [ CMP ] [ CMOVG ] 2bi ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %min-float double-rep two-operand MINSD ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %min-vector
[ two-operand ] keep {
{ char-16-rep [ PMINSB ] }
{ uchar-16-rep [ PMINUB ] }
{ short-8-rep [ PMINSW ] }
{ ushort-8-rep [ PMINUW ] }
{ int-4-rep [ PMINSD ] }
{ uint-4-rep [ PMINUD ] }
{ float-4-rep [ MINPS ] }
{ double-2-rep [ MINPD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %min-vector-reps
{
{ sse? { float-4-rep } }
{ sse2? { uchar-16-rep short-8-rep double-2-rep } }
{
sse4.1?
{ char-16-rep ushort-8-rep int-4-rep uint-4-rep }
}
} available-reps ;


USING: cpu.architecture cpu.x86.sse kernel system ;

M: x86 %move-vector-mask (%move-vector-mask) drop ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %move-vector-mask-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %mul int-rep two-operand IMUL2 ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %mul-float double-rep two-operand MULSD ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %mul-high-vector
[ two-operand ] keep
{ { short-8-rep [ PMULHW ] } { ushort-8-rep [ PMULHUW ] } }
case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %mul-high-vector-reps
{ { sse2? { short-8-rep ushort-8-rep } } } available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %mul-horizontal-add-vector
[ two-operand ] keep {
{ char-16-rep [ PMADDUBSW ] }
{ uchar-16-rep [ PMADDUBSW ] }
{ short-8-rep [ PMADDWD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %mul-horizontal-add-vector-reps
{
{ sse2? { short-8-rep } }
{ ssse3? { char-16-rep uchar-16-rep } }
} available-reps ;


USING: cpu.architecture cpu.x86.assembler system ;

M: x86 %mul-imm IMUL3 ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %mul-vector
[ two-operand ] keep {
{ float-4-rep [ MULPS ] }
{ double-2-rep [ MULPD ] }
{ short-8-rep [ PMULLW ] }
{ ushort-8-rep [ PMULLW ] }
{ int-4-rep [ PMULLD ] }
{ uint-4-rep [ PMULLD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %mul-vector-reps
{
{ sse? { float-4-rep } }
{ sse2? { double-2-rep short-8-rep ushort-8-rep } }
{ sse4.1? { int-4-rep uint-4-rep } }
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %neg int-rep one-operand NEG ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %not int-rep one-operand NOT ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %or int-rep two-operand OR ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %or-imm int-rep two-operand OR ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %or-vector
[ two-operand ] keep {
{ float-4-rep [ ORPS ] }
{ double-2-rep [ ORPS ] }
[ drop POR ]
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %or-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %peek loc>operand MOV ;


USING: cpu.architecture cpu.x86 layouts math system ;

M: x86 %prologue cell - decr-stack-reg ;


USING: cpu.architecture locals system ;

M:: x86 %reload ( dst rep src -- ) dst src rep %copy ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler kernel system
;

M: x86 %replace loc>operand swap MOV ;


USING: combinators compiler.codegen.relocation
compiler.constants cpu.architecture cpu.x86 cpu.x86.assembler
kernel layouts math system ;

M: x86 %replace-imm
loc>operand swap {
{ [ dup not ] [ drop \ f type-number MOV ] }
{ [ dup fixnum? ] [ tag-fixnum MOV ] }
[ [ 4294967295 MOV ] dip rc-absolute rel-literal ]
} cond ;


USING: cpu.architecture cpu.x86.assembler system ;

M: x86 %return 0 RET ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %sad-vector
[ two-operand ] keep { { uchar-16-rep [ PSADBW ] } } case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %sad-vector-reps
{ { sse2? { uchar-16-rep } } } available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %sar int-rep two-operand [ SAR ] emit-shift ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %sar-imm int-rep two-operand SAR ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %saturated-add-vector
[ two-operand ] keep {
{ char-16-rep [ PADDSB ] }
{ uchar-16-rep [ PADDUSB ] }
{ short-8-rep [ PADDSW ] }
{ ushort-8-rep [ PADDUSW ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %saturated-add-vector-reps
{
{
sse2?
{
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %saturated-sub-vector
[ two-operand ] keep {
{ char-16-rep [ PSUBSB ] }
{ uchar-16-rep [ PSUBUSB ] }
{ short-8-rep [ PSUBSW ] }
{ ushort-8-rep [ PSUBUSW ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %saturated-sub-vector-reps
{
{
sse2?
{
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler
cpu.x86.assembler.operands layouts locals math system vm ;

M:: x86 %save-context ( temp1 temp2 -- )
temp1 %context temp2 stack-reg cell neg [+] LEA
temp1 "callstack-top" context-field-offset [+] temp2 MOV
temp1 "datastack" context-field-offset [+] ds-reg MOV
temp1 "retainstack" context-field-offset [+] rs-reg MOV ;


USING: cpu.architecture system ;

M: x86 %scalar>vector %copy ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler kernel system
;

M: x86 %set-slot (%slot) swap MOV ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler kernel system
;

M: x86 %set-slot-imm (%slot-imm) swap MOV ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %shl int-rep two-operand [ SHL ] emit-shift ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %shl-imm int-rep two-operand SHL ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %shl-vector
[ two-operand ] keep {
{ short-8-rep [ PSLLW ] }
{ ushort-8-rep [ PSLLW ] }
{ int-4-rep [ PSLLD ] }
{ uint-4-rep [ PSLLD ] }
{ longlong-2-rep [ PSLLQ ] }
{ ulonglong-2-rep [ PSLLQ ] }
} case ;


USING: cpu.architecture system ;

M: x86 %shl-vector-imm %shl-vector ;


USING: cpu.architecture system ;

M: x86 %shl-vector-imm-reps %shl-vector-reps ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %shl-vector-reps
{
{
sse2?
{
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %shr int-rep two-operand [ SHR ] emit-shift ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %shr-imm int-rep two-operand SHR ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %shr-vector
[ two-operand ] keep {
{ short-8-rep [ PSRAW ] }
{ ushort-8-rep [ PSRLW ] }
{ int-4-rep [ PSRAD ] }
{ uint-4-rep [ PSRLD ] }
{ ulonglong-2-rep [ PSRLQ ] }
} case ;


USING: cpu.architecture system ;

M: x86 %shr-vector-imm %shr-vector ;


USING: cpu.architecture system ;

M: x86 %shr-vector-imm-reps %shr-vector-reps ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %shr-vector-reps
{
{
sse2?
{
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %shuffle-vector two-operand PSHUFB ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
cpu.x86.sse locals system ;

M:: x86 %shuffle-vector-halves-imm
( dst src1 src2 shuffle rep -- )
dst src1 src2 rep two-operand shuffle rep {
{ double-2-rep [ >float-4-shuffle SHUFPS ] }
{ float-4-rep [ SHUFPS ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %shuffle-vector-halves-imm-reps
{ { sse? { float-4-rep } } { sse2? { double-2-rep } } }
available-reps ;


USING: combinators cpu.architecture cpu.x86.sse locals system ;

M:: x86 %shuffle-vector-imm ( dst src shuffle rep -- )
dst src rep %copy dst shuffle rep signed-rep {
{ double-2-rep [ >float-4-shuffle float-4-shuffle ] }
{ float-4-rep [ float-4-shuffle ] }
{ int-4-rep [ int-4-shuffle ] }
{ longlong-2-rep [ longlong-2-shuffle ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %shuffle-vector-imm-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %shuffle-vector-reps
{
{
ssse3?
{
float-4-rep
double-2-rep
longlong-2-rep
ulonglong-2-rep
int-4-rep
uint-4-rep
short-8-rep
ushort-8-rep
char-16-rep
uchar-16-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %signed-pack-vector
[ two-operand ] keep
{ { int-4-rep [ PACKSSDW ] } { short-8-rep [ PACKSSWB ] } }
case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %signed-pack-vector-reps
{ { sse2? { short-8-rep int-4-rep } } } available-reps ;


USING: cpu.architecture cpu.x86.assembler cpu.x86.sse kernel
system ;

M: x86 %single>double-float
[ %clear-unless-in-place ] [ CVTSS2SD ] 2bi ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %slot (%slot) MOV ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %slot-imm (%slot-imm) MOV ;


USING: cpu.architecture locals system ;

M:: x86 %spill ( src rep dst -- ) dst src rep %copy ;


USING: cpu.architecture cpu.x86.assembler system ;

M: x86 %sqrt SQRTSD ;


USING: combinators cpu.architecture cpu.x86.assembler system ;

M: x86 %sqrt-vector
{ { float-4-rep [ SQRTPS ] } { double-2-rep [ SQRTPD ] } }
case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %sqrt-vector-reps
{ { sse? { float-4-rep } } { sse2? { double-2-rep } } }
available-reps ;


USING: cpu.architecture cpu.x86 system ;

M: x86 %store-memory (%memory) (%store-memory) ;


USING: cpu.architecture cpu.x86 system ;

M: x86 %store-memory-imm (%memory-imm) (%store-memory) ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %sub int-rep two-operand SUB ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %sub-float double-rep two-operand SUBSD ;


USING: cpu.architecture cpu.x86.assembler
cpu.x86.assembler.operands kernel math system ;

M: x86 %sub-imm 2over eq? [ nip SUB ] [ neg [+] LEA ] if ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %sub-vector
[ two-operand ] keep {
{ float-4-rep [ SUBPS ] }
{ double-2-rep [ SUBPD ] }
{ char-16-rep [ PSUBB ] }
{ uchar-16-rep [ PSUBB ] }
{ short-8-rep [ PSUBW ] }
{ ushort-8-rep [ PSUBW ] }
{ int-4-rep [ PSUBD ] }
{ uint-4-rep [ PSUBD ] }
{ longlong-2-rep [ PSUBQ ] }
{ ulonglong-2-rep [ PSUBQ ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %sub-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86.assembler kernel
system ;

M: x86 %tail>head-vector
dup {
{ float-4-rep [ drop UNPCKHPD ] }
{ double-2-rep [ drop UNPCKHPD ] }
[ drop [ %copy ] [ drop PUNPCKHQDQ ] 3bi ]
} case ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %test ( dst src1 src2 cc temp -- )
src1 src2 TEST dst cc temp %boolean ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %test-branch ( label src1 src2 cc -- )
src1 src2 TEST label cc %branch ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %test-imm ( dst src1 src2 cc temp -- )
src1 src2 TEST dst cc temp %boolean ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %test-imm-branch ( label src1 src2 cc -- )
src1 src2 TEST label cc %branch ;


USING: cpu.architecture cpu.x86.sse locals system ;

M:: x86 %test-vector ( dst src temp rep vcc -- )
dst src rep (%move-vector-mask)
:> mask dst temp mask vcc %test-vector-mask ;


USING: cpu.architecture cpu.x86.sse locals system ;

M:: x86 %test-vector-branch ( label src temp rep vcc -- )
temp src rep (%move-vector-mask)
:> mask label temp mask vcc %test-vector-mask-branch ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %test-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: compiler.constants cpu.architecture cpu.x86.assembler
cpu.x86.assembler.operands system ;

M: x86 %unbox-alien alien-offset [+] MOV ;


USING: alien compiler.codegen.labels compiler.constants
cpu.architecture cpu.x86.assembler cpu.x86.assembler.operands
layouts locals namespaces system ;

M:: x86 %unbox-any-c-ptr ( dst src -- )
[
"end" define-label dst dst XOR src \ f type-number CMP
"end" get JE dst src MOV dst tag-mask get AND
dst alien type-number CMP dst src byte-array-offset [+]
LEA "end" get JNE dst src alien-offset [+] MOV
"end" resolve-label
] with-scope ;


USING: combinators cpu.architecture cpu.x86.assembler system ;

M: x86 %unpack-vector-head
{
{ char-16-rep [ PMOVSXBW ] }
{ uchar-16-rep [ PMOVZXBW ] }
{ short-8-rep [ PMOVSXWD ] }
{ ushort-8-rep [ PMOVZXWD ] }
{ int-4-rep [ PMOVSXDQ ] }
{ uint-4-rep [ PMOVZXDQ ] }
{ float-4-rep [ CVTPS2PD ] }
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %unpack-vector-head-reps
{
{ sse2? { float-4-rep } }
{
sse4.1?
{
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %unsigned-pack-vector
[ two-operand ] keep signed-rep
{ { int-4-rep [ PACKUSDW ] } { short-8-rep [ PACKUSWB ] } }
case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %unsigned-pack-vector-reps
{ { sse2? { short-8-rep } } { sse4.1? { int-4-rep } } }
available-reps ;


USING: cpu.architecture system ;

M: x86 %vector>scalar %copy ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %write-barrier
( src slot scale tag temp1 temp2 -- )
temp1 src slot scale tag (%slot) LEA
temp1 temp2 (%write-barrier) ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler locals system
;

M:: x86 %write-barrier-imm ( src slot tag temp1 temp2 -- )
temp1 src slot tag (%slot-imm) LEA
temp1 temp2 (%write-barrier) ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %xor int-rep two-operand XOR ;


USING: cpu.architecture cpu.x86 cpu.x86.assembler system ;

M: x86 %xor-imm int-rep two-operand XOR ;


USING: combinators cpu.architecture cpu.x86 cpu.x86.assembler
kernel system ;

M: x86 %xor-vector
[ two-operand ] keep {
{ float-4-rep [ XORPS ] }
{ double-2-rep [ XORPS ] }
[ drop PXOR ]
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %xor-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: combinators cpu.architecture cpu.x86.assembler kernel
system ;

M: x86 %zero-vector
{
{ double-2-rep [ dup XORPS ] }
{ float-4-rep [ dup XORPS ] }
[ drop dup PXOR ]
} case ;


USING: cpu.architecture cpu.x86.features cpu.x86.sse system ;

M: x86 %zero-vector-reps
{
{ sse? { float-4-rep } }
{
sse2?
{
double-2-rep
char-16-rep
uchar-16-rep
short-8-rep
ushort-8-rep
int-4-rep
uint-4-rep
longlong-2-rep
ulonglong-2-rep
}
}
} available-reps ;


USING: arrays cpu.x86.features kernel math.floats.env.private
math.floats.env.x86 system ;

M: x86 (fp-env-registers)
sse2?
[ <sse-env> <x87-env> 2array ] [ <x87-env> 1array ] if ;


USING: cpu.architecture system ;

M: x86 complex-addressing? t ;


USING: cpu.architecture system ;

M: x86 float-right-align-on-stack? f ;


USING: cpu.architecture system ;

M: x86 fused-unboxing? t ;


USING: accessors compiler.cfg.stack-frame cpu.architecture
cpu.x86 layouts math system ;

M: x86 gc-root-offset
n>> spill-offset special-offset cell + cell /i ;


USING: cpu.architecture math.order system ;

M: x86 immediate-arithmetic? -2147483648 2147483647 between? ;


USING: cpu.architecture math.order system ;

M: x86 immediate-bitwise? -2147483648 2147483647 between? ;


USING: cpu.architecture system ;

M: x86 immediate-store? immediate-comparand? ;


USING: cpu.architecture system ;

M: x86 integer-float-needs-stack-frame? f ;


USING: cpu.architecture system ;

M: x86 long-long-odd-register? f ;


USING: compiler.cfg.stack-frame cpu.architecture cpu.x86
layouts math system ;

M: x86 stack-frame-size
(stack-frame-size) reserved-stack-space + cell +
align-stack ;


USING: cpu.architecture system ;

M: x86 test-instruction? t ;


USING: cpu.architecture kernel system ;

M: x86 value-struct? drop t ;


USING: cpu.architecture system ;

M: x86 vector-regs float-regs ;