! Copyright (C) 2005, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs alien alien.c-types arrays strings cpu.x86.assembler cpu.x86.assembler.private cpu.architecture kernel kernel.private math memory namespaces make sequences words system layouts combinators math.order fry locals compiler.constants compiler.cfg.registers compiler.cfg.instructions compiler.cfg.intrinsics compiler.codegen compiler.codegen.fixup ; IN: cpu.x86 << enable-fixnum-log2 >> 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-reference swap 0 MOV rc-absolute-cell rel-immediate ; HOOK: ds-reg cpu ( -- reg ) HOOK: rs-reg cpu ( -- reg ) : reg-stack ( n reg -- op ) swap cells neg [+] ; GENERIC: loc>operand ( loc -- operand ) M: ds-loc loc>operand n>> ds-reg reg-stack ; M: rs-loc loc>operand n>> rs-reg reg-stack ; M: x86 %peek loc>operand MOV ; M: x86 %replace loc>operand swap MOV ; : (%inc) ( n reg -- ) swap cells dup 0 > [ ADD ] [ neg SUB ] if ; inline M: x86 %inc-d ( n -- ) ds-reg (%inc) ; M: x86 %inc-r ( n -- ) rs-reg (%inc) ; : align-stack ( n -- n' ) os macosx? cpu x86.64? or [ 16 align ] when ; HOOK: reserved-area-size cpu ( -- n ) M: x86 stack-frame-size ( stack-frame -- i ) [ spill-counts>> [ swap reg-size * ] { } assoc>map sum ] [ params>> ] [ return>> ] tri + + 3 cells + reserved-area-size + align-stack ; M: x86 %call ( label -- ) CALL ; M: x86 %jump-label ( label -- ) JMP ; M: x86 %return ( -- ) 0 RET ; : code-alignment ( align -- n ) [ building get [ integer? ] count dup ] dip align swap - ; : align-code ( n -- ) 0 % ; M: x86 %dispatch-label ( word -- ) 0 cell, rc-absolute-cell rel-word ; :: (%slot) ( obj slot tag temp -- op ) temp slot obj [+] LEA temp tag neg [+] ; inline :: (%slot-imm) ( obj slot tag -- op ) obj slot cells tag - [+] ; inline M: x86 %slot ( dst obj slot tag temp -- ) (%slot) MOV ; M: x86 %slot-imm ( dst obj slot tag -- ) (%slot-imm) MOV ; M: x86 %set-slot ( src obj slot tag temp -- ) (%slot) swap MOV ; M: x86 %set-slot-imm ( src obj slot tag -- ) (%slot-imm) swap MOV ; M: x86 %add [+] LEA ; M: x86 %add-imm [+] LEA ; M: x86 %sub nip SUB ; M: x86 %sub-imm neg [+] LEA ; M: x86 %mul nip swap IMUL2 ; M: x86 %mul-imm nip IMUL2 ; M: x86 %and nip AND ; M: x86 %and-imm nip AND ; M: x86 %or nip OR ; M: x86 %or-imm nip OR ; M: x86 %xor nip XOR ; M: x86 %xor-imm nip XOR ; M: x86 %shl-imm nip SHL ; M: x86 %shr-imm nip SHR ; M: x86 %sar-imm nip SAR ; M: x86 %not drop NOT ; M: x86 %log2 BSR ; : ?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 ; HOOK: %alien-invoke-tail cpu ( func dll -- ) :: overflow-template ( src1 src2 insn inverse func -- )