! 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.cfg.comparisons compiler.cfg.stack-frame compiler.codegen compiler.codegen.fixup ; IN: cpu.x86 << enable-fixnum-log2 >> ! Add some methods to the assembler to be more useful to the backend M: label JMP 0 JMP rc-relative label-fixup ; M: label JUMPcc [ 0 ] dip JUMPcc rc-relative label-fixup ; M: x86 two-operand? t ; HOOK: stack-reg cpu ( -- reg ) HOOK: reserved-area-size cpu ( -- n ) : stack@ ( n -- op ) stack-reg swap [+] ; : param@ ( n -- op ) reserved-area-size + stack@ ; : spill-integer@ ( n -- op ) spill-integer-offset param@ ; : spill-float@ ( n -- op ) spill-float-offset param@ ; : gc-root@ ( n -- op ) gc-root-offset param@ ; : decr-stack-reg ( n -- ) dup 0 = [ drop ] [ stack-reg swap SUB ] if ; : incr-stack-reg ( n -- ) dup 0 = [ drop ] [ stack-reg swap ADD ] if ; : align-stack ( n -- n' ) os macosx? cpu x86.64? or [ 16 align ] when ; M: x86 stack-frame-size ( stack-frame -- i ) (stack-frame-size) 3 cells reserved-area-size + + align-stack ; HOOK: temp-reg-1 cpu ( -- reg ) HOOK: temp-reg-2 cpu ( -- reg ) HOOK: param-reg-1 cpu ( -- reg ) HOOK: param-reg-2 cpu ( -- reg ) HOOK: pic-tail-reg 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) ; M: x86 %call ( word -- ) 0 CALL rc-relative rel-word-pic ; : xt-tail-pic-offset ( -- n ) #! See the comment in vm/cpu-x86.hpp cell 4 + 1 + ; inline M: x86 %jump ( word -- ) pic-tail-reg 0 MOV xt-tail-pic-offset rc-absolute-cell rel-here 0 JMP rc-relative rel-word-pic-tail ; M: x86 %jump-label ( label -- ) 0 JMP rc-relative label-fixup ; M: x86 %return ( -- ) 0 RET ; : code-alignment ( align -- n ) [ building get length dup ] dip align swap - ; : align-code ( n -- ) 0 % ; :: (%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 IMUL3 ; 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 -- )