2006-04-03 02:18:56 -04:00
|
|
|
IN: compiler
|
2006-05-09 11:31:10 -04:00
|
|
|
USING: arrays generic kernel kernel-internals math memory
|
|
|
|
namespaces sequences ;
|
2005-09-04 19:24:24 -04:00
|
|
|
|
2006-08-08 01:38:32 -04:00
|
|
|
! Does the assembler emit bytes or cells?
|
|
|
|
DEFER: code-format ( -- byte# )
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
! A scratch register for computations
|
|
|
|
TUPLE: vreg n ;
|
2005-09-04 19:24:24 -04:00
|
|
|
|
2006-05-04 18:08:52 -04:00
|
|
|
C: vreg ( n reg-class -- vreg )
|
|
|
|
[ set-delegate ] keep [ set-vreg-n ] keep ;
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
! Register classes
|
|
|
|
TUPLE: int-regs ;
|
|
|
|
TUPLE: float-regs size ;
|
2005-09-09 22:34:24 -04:00
|
|
|
|
2006-05-04 18:08:52 -04:00
|
|
|
: <int-vreg> ( n -- vreg ) T{ int-regs } <vreg> ;
|
|
|
|
: <float-vreg> ( n -- vreg ) T{ float-regs f 8 } <vreg> ;
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
! A pseudo-register class for parameters spilled on the stack
|
|
|
|
TUPLE: stack-params ;
|
|
|
|
|
|
|
|
! Return values of this class go here
|
|
|
|
GENERIC: return-reg ( register-class -- reg )
|
|
|
|
|
|
|
|
! Sequence of registers used for parameter passing in class
|
|
|
|
GENERIC: fastcall-regs ( register-class -- regs )
|
|
|
|
|
|
|
|
! Sequence mapping vreg-n to native assembler registers
|
2006-05-04 18:08:52 -04:00
|
|
|
GENERIC: vregs ( register-class -- regs )
|
2005-10-21 03:42:38 -04:00
|
|
|
|
2006-05-05 20:06:57 -04:00
|
|
|
! Map a sequence of literals to f or float
|
|
|
|
DEFER: literal-template ( literals -- template )
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
! Load a literal (immediate or indirect)
|
|
|
|
G: load-literal ( obj vreg -- ) 1 standard-combination ;
|
|
|
|
|
|
|
|
! Set up caller stack frame (PowerPC and AMD64)
|
2006-04-29 18:33:05 -04:00
|
|
|
: %prologue ( n -- ) drop ; inline
|
2006-04-28 19:23:50 -04:00
|
|
|
|
|
|
|
! Tear down stack frame (PowerPC and AMD64)
|
2006-04-29 18:33:05 -04:00
|
|
|
: %epilogue ( -- ) ; inline
|
2006-04-28 18:38:48 -04:00
|
|
|
|
|
|
|
! Tail call another word
|
|
|
|
DEFER: %jump ( label -- )
|
|
|
|
|
|
|
|
! Call another word
|
|
|
|
DEFER: %call ( label -- )
|
|
|
|
|
|
|
|
! Local jump for branches or tail calls in nested #label
|
|
|
|
DEFER: %jump-label ( label -- )
|
|
|
|
|
|
|
|
! Test if vreg is 'f' or not
|
|
|
|
DEFER: %jump-t ( label vreg -- )
|
|
|
|
|
|
|
|
! Jump table of addresses (one cell each) is right after this
|
|
|
|
DEFER: %dispatch ( vreg -- )
|
|
|
|
|
2006-08-09 18:25:11 -04:00
|
|
|
! Jump table entry
|
|
|
|
DEFER: %target ( label -- )
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
! Return to caller
|
|
|
|
DEFER: %return ( -- )
|
|
|
|
|
|
|
|
! Change datastack height
|
|
|
|
DEFER: %inc-d ( n -- )
|
|
|
|
|
|
|
|
! Change callstack height
|
|
|
|
DEFER: %inc-r ( n -- )
|
|
|
|
|
|
|
|
! Load stack into vreg
|
2006-05-09 21:37:07 -04:00
|
|
|
GENERIC: (%peek) ( vreg loc reg-class -- )
|
|
|
|
: %peek ( vreg loc -- ) over (%peek) ;
|
2006-04-28 18:38:48 -04:00
|
|
|
|
|
|
|
! Store vreg to stack
|
2006-05-09 21:37:07 -04:00
|
|
|
GENERIC: (%replace) ( vreg loc reg-class -- )
|
|
|
|
: %replace ( vreg loc -- ) over (%replace) ;
|
2006-04-28 18:38:48 -04:00
|
|
|
|
2006-05-09 11:31:10 -04:00
|
|
|
! Move one vreg to another
|
|
|
|
DEFER: %move-int>int ( dst src -- )
|
|
|
|
DEFER: %move-int>float ( dst src -- )
|
|
|
|
|
|
|
|
: %move ( dst src -- )
|
|
|
|
2dup = [
|
|
|
|
2drop
|
|
|
|
] [
|
|
|
|
2dup [ delegate class ] 2apply 2array {
|
2006-05-09 12:38:57 -04:00
|
|
|
{ [ dup { int-regs int-regs } = ] [ drop %move-int>int ] }
|
|
|
|
{ [ dup { float-regs int-regs } = ] [ drop %move-int>float ] }
|
2006-05-09 11:31:10 -04:00
|
|
|
} cond
|
|
|
|
] if ;
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
! FFI stuff
|
|
|
|
DEFER: %unbox ( n reg-class func -- )
|
|
|
|
|
2006-07-03 02:52:44 -04:00
|
|
|
DEFER: %unbox-struct ( n size -- )
|
2006-04-28 18:38:48 -04:00
|
|
|
|
|
|
|
DEFER: %box ( n reg-class func -- )
|
|
|
|
|
2006-07-03 02:52:44 -04:00
|
|
|
DEFER: %box-struct ( n size -- )
|
2006-04-28 18:38:48 -04:00
|
|
|
|
2006-05-11 02:22:51 -04:00
|
|
|
GENERIC: %freg>stack ( stack reg reg-class -- )
|
2006-05-09 12:38:57 -04:00
|
|
|
|
2006-05-11 02:22:51 -04:00
|
|
|
GENERIC: %stack>freg ( stack reg reg-class -- )
|
2006-05-09 12:38:57 -04:00
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
DEFER: %alien-invoke ( library function -- )
|
|
|
|
|
2006-05-09 12:38:57 -04:00
|
|
|
DEFER: %cleanup ( n -- )
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
DEFER: %alien-callback ( quot -- )
|
|
|
|
|
|
|
|
DEFER: %callback-value ( reg-class func -- )
|
|
|
|
|
|
|
|
M: stack-params fastcall-regs drop 0 ;
|
|
|
|
|
|
|
|
GENERIC: reg-size ( register-class -- n )
|
|
|
|
|
|
|
|
GENERIC: inc-reg-class ( register-class -- )
|
|
|
|
|
|
|
|
M: int-regs reg-size drop cell ;
|
|
|
|
|
|
|
|
: (inc-reg-class)
|
|
|
|
dup class inc
|
|
|
|
macosx? [ reg-size stack-params +@ ] [ drop ] if ;
|
|
|
|
|
|
|
|
M: int-regs inc-reg-class
|
|
|
|
(inc-reg-class) ;
|
|
|
|
|
|
|
|
M: float-regs reg-size float-regs-size ;
|
|
|
|
|
|
|
|
M: float-regs inc-reg-class
|
|
|
|
dup (inc-reg-class)
|
|
|
|
macosx? [ reg-size 4 / int-regs +@ ] [ drop ] if ;
|
|
|
|
|
2006-08-15 04:57:12 -04:00
|
|
|
GENERIC: v>operand ( obj -- operand )
|
2006-04-28 18:38:48 -04:00
|
|
|
M: integer v>operand tag-bits shift ;
|
2006-05-04 18:08:52 -04:00
|
|
|
M: vreg v>operand dup vreg-n swap vregs nth ;
|
2006-08-08 01:38:32 -04:00
|
|
|
M: f v>operand drop object-tag ;
|