! Copyright (C) 2005, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien arrays assembler generic kernel kernel-internals math memory namespaces sequences words ; IN: compiler ! x86 register assignments ! EAX, ECX, EDX integer vregs ! XMM0 - XMM7 float vregs ! ESI datastack ! EBX callstack ! AMD64 redefines a lot of words in this file : ds-reg ESI ; inline : cs-reg EBX ; inline : remainder-reg EDX ; inline : reg-stack ( n reg -- op ) swap cells neg [+] ; M: ds-loc v>operand ds-loc-n ds-reg reg-stack ; M: cs-loc v>operand cs-loc-n cs-reg reg-stack ; : %alien-invoke ( symbol dll -- ) 2dup dlsym CALL rel-relative rel-dlsym ; : compile-c-call* ( symbol dll args -- operands ) reverse-slice [ [ PUSH ] each %alien-invoke ] keep [ drop EDX POP ] each ; ! On x86, parameters are never passed in registers. M: int-regs return-reg drop EAX ; M: int-regs fastcall-regs drop { } ; M: int-regs vregs drop { EAX ECX EDX } ; M: float-regs fastcall-regs drop { } ; M: float-regs vregs drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; : address-operand ( address -- operand ) #! On x86, we can always use an address as an operand #! directly. ; inline : fixnum>slot@ 1 SHR ; inline : prepare-division CDQ ; inline : unboxify-float ( obj vreg quot -- | quot: obj int-vreg ) over [ float-regs? ] is? [ swap >r T{ int-regs } alloc-reg [ swap call ] keep r> swap [ v>operand ] 2apply float-offset [+] MOVSD ] [ call ] if ; inline M: immediate load-literal ( literal vreg -- ) v>operand swap v>operand MOV ; : load-indirect ( literal vreg -- ) v>operand swap add-literal [] MOV rel-absolute-cell rel-address ; M: object load-literal ( literal vreg -- ) [ load-indirect ] unboxify-float ; : (%call) ( label -- label ) dup postpone-word dup primitive? [ address-operand ] when ; : %call ( label -- ) (%call) CALL ; : %jump ( label -- ) %epilogue (%call) JMP ; : %jump-label ( label -- ) JMP ; : %jump-t ( label -- ) "flag" operand f v>operand CMP JNE ; : %dispatch ( -- ) #! Compile a piece of code that jumps to an offset in a #! jump table indexed by the fixnum at the top of the stack. #! The jump table must immediately follow this macro.