cpu.x86.32: only create 16-byte parameter area if the word calls into the VM
							parent
							
								
									bcf57c5940
								
							
						
					
					
						commit
						18be7e1f37
					
				| 
						 | 
				
			
			@ -27,7 +27,9 @@ M: ##call compute-stack-frame*
 | 
			
		|||
 | 
			
		||||
M: ##gc compute-stack-frame*
 | 
			
		||||
    frame-required? on
 | 
			
		||||
    stack-frame new swap tagged-values>> length cells >>gc-root-size
 | 
			
		||||
    stack-frame new
 | 
			
		||||
        swap tagged-values>> length cells >>gc-root-size
 | 
			
		||||
        t >>calls-vm?
 | 
			
		||||
    request-stack-frame ;
 | 
			
		||||
 | 
			
		||||
M: _spill-area-size compute-stack-frame*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,7 +212,8 @@ M: #terminate emit-node drop ##no-tco end-basic-block ;
 | 
			
		|||
    stack-frame new
 | 
			
		||||
        swap
 | 
			
		||||
        [ return>> return-size >>return ]
 | 
			
		||||
        [ alien-parameters parameter-offsets drop >>params ] bi ;
 | 
			
		||||
        [ alien-parameters parameter-offsets drop >>params ] bi
 | 
			
		||||
        t >>calls-vm? ;
 | 
			
		||||
 | 
			
		||||
: alien-node-height ( params -- )
 | 
			
		||||
    [ out-d>> length ] [ in-d>> length ] bi - adjust-d ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,8 @@ TUPLE: stack-frame
 | 
			
		|||
{ return integer }
 | 
			
		||||
{ total-size integer }
 | 
			
		||||
{ gc-root-size integer }
 | 
			
		||||
{ spill-area-size integer } ;
 | 
			
		||||
{ spill-area-size integer }
 | 
			
		||||
{ calls-vm? boolean } ;
 | 
			
		||||
 | 
			
		||||
! Stack frame utilities
 | 
			
		||||
: param-base ( -- n )
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +36,9 @@ TUPLE: stack-frame
 | 
			
		|||
 | 
			
		||||
: max-stack-frame ( frame1 frame2 -- frame3 )
 | 
			
		||||
    [ stack-frame new ] 2dip
 | 
			
		||||
    {
 | 
			
		||||
        [ [ params>> ] bi@ max >>params ]
 | 
			
		||||
        [ [ return>> ] bi@ max >>return ]
 | 
			
		||||
        [ [ gc-root-size>> ] bi@ max >>gc-root-size ]
 | 
			
		||||
        2tri ;
 | 
			
		||||
        [ [ calls-vm?>> ] bi@ or >>calls-vm? ]
 | 
			
		||||
    } 2cleave ;
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +25,11 @@ M: x86.32 rs-reg EDI ;
 | 
			
		|||
M: x86.32 stack-reg ESP ;
 | 
			
		||||
M: x86.32 temp-reg ECX ;
 | 
			
		||||
 | 
			
		||||
: local@ ( n -- op )
 | 
			
		||||
    stack-frame get extra-stack-space dup 16 assert= + stack@ ;
 | 
			
		||||
 | 
			
		||||
M: x86.32 extra-stack-space calls-vm?>> 16 0 ? ;
 | 
			
		||||
 | 
			
		||||
M: x86.32 %mark-card
 | 
			
		||||
    drop HEX: ffffffff [+] card-mark <byte> MOV
 | 
			
		||||
    building get pop
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +62,7 @@ M:: x86.32 %dispatch ( src temp -- )
 | 
			
		|||
 | 
			
		||||
M: x86.32 pic-tail-reg EBX ;
 | 
			
		||||
 | 
			
		||||
M: x86.32 reserved-area-size 4 cells ;
 | 
			
		||||
M: x86.32 reserved-stack-space 4 cells ;
 | 
			
		||||
 | 
			
		||||
M: x86.32 %alien-invoke 0 CALL rc-relative rel-dlsym ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +77,7 @@ M: x86.32 return-struct-in-registers? ( c-type -- ? )
 | 
			
		|||
    and or ;
 | 
			
		||||
 | 
			
		||||
: struct-return@ ( n -- operand )
 | 
			
		||||
    [ next-stack@ ] [ stack-frame get params>> param@ ] if* ;
 | 
			
		||||
    [ next-stack@ ] [ stack-frame get params>> local@ ] if* ;
 | 
			
		||||
 | 
			
		||||
! On x86, parameters are never passed in registers.
 | 
			
		||||
M: int-regs return-reg drop EAX ;
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +103,7 @@ M: x86.32 %prologue ( n -- )
 | 
			
		|||
 | 
			
		||||
M: x86.32 %load-param-reg
 | 
			
		||||
    stack-params assert=
 | 
			
		||||
    [ [ EAX ] dip param@ MOV ] dip
 | 
			
		||||
    [ [ EAX ] dip local@ MOV ] dip
 | 
			
		||||
    stack@ EAX MOV ;
 | 
			
		||||
 | 
			
		||||
M: x86.32 %save-param-reg 3drop ;
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +145,7 @@ M: x86.32 %prepare-box-struct ( -- )
 | 
			
		|||
    ! Compute target address for value struct return
 | 
			
		||||
    EAX f struct-return@ LEA
 | 
			
		||||
    ! Store it as the first parameter
 | 
			
		||||
    0 param@ EAX MOV ;
 | 
			
		||||
    0 local@ EAX MOV ;
 | 
			
		||||
 | 
			
		||||
M: x86.32 %box-small-struct ( c-type -- )
 | 
			
		||||
    #! Box a <= 8-byte struct returned in EAX:EDX. OS X only.
 | 
			
		||||
| 
						 | 
				
			
			@ -165,14 +170,14 @@ M: x86.32 %unbox ( n rep func -- )
 | 
			
		|||
    #! a parameter to a C function about to be called.
 | 
			
		||||
    call-unbox-func
 | 
			
		||||
    ! Store the return value on the C stack
 | 
			
		||||
    over [ [ param@ ] dip store-return-reg ] [ 2drop ] if ;
 | 
			
		||||
    over [ [ local@ ] dip store-return-reg ] [ 2drop ] if ;
 | 
			
		||||
 | 
			
		||||
M: x86.32 %unbox-long-long ( n func -- )
 | 
			
		||||
    call-unbox-func
 | 
			
		||||
    ! Store the return value on the C stack
 | 
			
		||||
    [
 | 
			
		||||
        dup param@ EAX MOV
 | 
			
		||||
        4 + param@ EDX MOV
 | 
			
		||||
        [ local@ EAX MOV ]
 | 
			
		||||
        [ 4 + local@ EDX MOV ] bi
 | 
			
		||||
    ] when* ;
 | 
			
		||||
 | 
			
		||||
: %unbox-struct-1 ( -- )
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +208,7 @@ M: x86 %unbox-small-struct ( size -- )
 | 
			
		|||
M:: x86.32 %unbox-large-struct ( n c-type -- )
 | 
			
		||||
    ! Alien must be in EAX.
 | 
			
		||||
    ! Compute destination address
 | 
			
		||||
    EDX n param@ LEA
 | 
			
		||||
    EDX n local@ LEA
 | 
			
		||||
    12 save-vm-ptr
 | 
			
		||||
    8 stack@ c-type heap-size MOV
 | 
			
		||||
    4 stack@ EDX MOV
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +312,7 @@ M: x86.32 %callback-return ( n -- )
 | 
			
		|||
    } cond RET ;
 | 
			
		||||
 | 
			
		||||
M:: x86.32 %call-gc ( gc-root-count temp -- )
 | 
			
		||||
    temp gc-root-base param@ LEA
 | 
			
		||||
    temp gc-root-base special@ LEA
 | 
			
		||||
    8 save-vm-ptr
 | 
			
		||||
    4 stack@ gc-root-count MOV
 | 
			
		||||
    0 stack@ temp MOV
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,22 @@ compiler.cfg.builder compiler.cfg.intrinsics compiler.cfg.stack-frame
 | 
			
		|||
cpu.x86.assembler cpu.x86.assembler.operands cpu.x86 cpu.architecture ;
 | 
			
		||||
IN: cpu.x86.64
 | 
			
		||||
 | 
			
		||||
: param-reg-1 ( -- reg ) int-regs param-regs first ; inline
 | 
			
		||||
: param-reg-2 ( -- reg ) int-regs param-regs second ; inline
 | 
			
		||||
: param-reg-3 ( -- reg ) int-regs param-regs third ; inline
 | 
			
		||||
: param-reg-4 ( -- reg ) int-regs param-regs fourth ; inline
 | 
			
		||||
 | 
			
		||||
M: x86.64 pic-tail-reg RBX ;
 | 
			
		||||
 | 
			
		||||
M: int-regs return-reg drop RAX ;
 | 
			
		||||
M: float-regs return-reg drop XMM0 ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 ds-reg R14 ;
 | 
			
		||||
M: x86.64 rs-reg R15 ;
 | 
			
		||||
M: x86.64 stack-reg RSP ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 extra-stack-space drop 0 ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 machine-registers
 | 
			
		||||
    {
 | 
			
		||||
        { int-regs { RAX RCX RDX RBX RBP RSI RDI R8 R9 R10 R11 R12 R13 } }
 | 
			
		||||
| 
						 | 
				
			
			@ -17,9 +33,13 @@ M: x86.64 machine-registers
 | 
			
		|||
        } }
 | 
			
		||||
    } ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 ds-reg R14 ;
 | 
			
		||||
M: x86.64 rs-reg R15 ;
 | 
			
		||||
M: x86.64 stack-reg RSP ;
 | 
			
		||||
: param@ ( n -- op ) reserved-stack-space + stack@ ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 %prologue ( n -- )
 | 
			
		||||
    temp-reg 0 MOV rc-absolute-cell rel-this
 | 
			
		||||
    dup PUSH
 | 
			
		||||
    temp-reg PUSH
 | 
			
		||||
    stack-reg swap 3 cells - SUB ;
 | 
			
		||||
 | 
			
		||||
: load-cards-offset ( dst -- )
 | 
			
		||||
    0 MOV rc-absolute-cell rel-cards-offset ;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,22 +70,6 @@ M:: x86.64 %dispatch ( src temp -- )
 | 
			
		|||
    [ align-code ]
 | 
			
		||||
    bi ;
 | 
			
		||||
 | 
			
		||||
: param-reg-1 ( -- reg ) int-regs param-regs first ; inline
 | 
			
		||||
: param-reg-2 ( -- reg ) int-regs param-regs second ; inline
 | 
			
		||||
: param-reg-3 ( -- reg ) int-regs param-regs third ; inline
 | 
			
		||||
: param-reg-4 ( -- reg ) int-regs param-regs fourth ; inline
 | 
			
		||||
 | 
			
		||||
M: x86.64 pic-tail-reg RBX ;
 | 
			
		||||
 | 
			
		||||
M: int-regs return-reg drop RAX ;
 | 
			
		||||
M: float-regs return-reg drop XMM0 ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 %prologue ( n -- )
 | 
			
		||||
    temp-reg 0 MOV rc-absolute-cell rel-this
 | 
			
		||||
    dup PUSH
 | 
			
		||||
    temp-reg PUSH
 | 
			
		||||
    stack-reg swap 3 cells - SUB ;
 | 
			
		||||
 | 
			
		||||
M: stack-params copy-register*
 | 
			
		||||
    drop
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ M: int-regs param-regs
 | 
			
		|||
M: float-regs param-regs
 | 
			
		||||
    drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 reserved-area-size 0 ;
 | 
			
		||||
M: x86.64 reserved-stack-space 0 ;
 | 
			
		||||
 | 
			
		||||
SYMBOL: (stack-value)
 | 
			
		||||
! The ABI for passing structs by value is pretty great
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ M: int-regs param-regs drop { RCX RDX R8 R9 } ;
 | 
			
		|||
 | 
			
		||||
M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 } ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 reserved-area-size 4 cells ;
 | 
			
		||||
M: x86.64 reserved-stack-space 4 cells ;
 | 
			
		||||
 | 
			
		||||
M: x86.64 return-struct-in-registers? ( c-type -- ? )
 | 
			
		||||
    heap-size { 1 2 4 8 } member? ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,15 +24,20 @@ M: x86 vector-regs float-regs ;
 | 
			
		|||
 | 
			
		||||
HOOK: stack-reg cpu ( -- reg )
 | 
			
		||||
 | 
			
		||||
HOOK: reserved-area-size cpu ( -- n )
 | 
			
		||||
HOOK: reserved-stack-space cpu ( -- n )
 | 
			
		||||
 | 
			
		||||
HOOK: extra-stack-space cpu ( stack-frame -- n )
 | 
			
		||||
 | 
			
		||||
: stack@ ( n -- op ) stack-reg swap [+] ;
 | 
			
		||||
 | 
			
		||||
: param@ ( n -- op ) reserved-area-size + stack@ ;
 | 
			
		||||
: special@ ( n -- op )
 | 
			
		||||
    stack-frame get extra-stack-space +
 | 
			
		||||
    reserved-stack-space +
 | 
			
		||||
    stack@ ;
 | 
			
		||||
 | 
			
		||||
: spill@ ( n -- op ) spill-offset param@ ;
 | 
			
		||||
: spill@ ( n -- op ) spill-offset special@ ;
 | 
			
		||||
 | 
			
		||||
: gc-root@ ( n -- op ) gc-root-offset param@ ;
 | 
			
		||||
: gc-root@ ( n -- op ) gc-root-offset special@ ;
 | 
			
		||||
 | 
			
		||||
: decr-stack-reg ( n -- )
 | 
			
		||||
    dup 0 = [ drop ] [ stack-reg swap SUB ] if ;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +49,11 @@ HOOK: reserved-area-size cpu ( -- 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 ;
 | 
			
		||||
    [ (stack-frame-size) ]
 | 
			
		||||
    [ extra-stack-space ] bi +
 | 
			
		||||
    reserved-stack-space +
 | 
			
		||||
    3 cells +
 | 
			
		||||
    align-stack ;
 | 
			
		||||
 | 
			
		||||
! Must be a volatile register not used for parameter passing, for safe
 | 
			
		||||
! use in calls in and out of C
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue