2009-05-29 14:11:34 -04:00
|
|
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
2008-10-28 05:38:37 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-07-27 23:28:29 -04:00
|
|
|
USING: accessors kernel sequences make combinators
|
|
|
|
compiler.cfg.registers compiler.cfg.instructions
|
2009-07-22 04:08:28 -04:00
|
|
|
compiler.cfg.rpo cpu.architecture ;
|
2008-10-28 05:38:37 -04:00
|
|
|
IN: compiler.cfg.two-operand
|
|
|
|
|
2009-08-05 19:57:46 -04:00
|
|
|
! This pass runs before SSA coalescing and normalizes instructions
|
|
|
|
! to fit the x86 two-address scheme. Since the input is in SSA,
|
|
|
|
! it suffices to convert
|
|
|
|
!
|
|
|
|
! x = y op z
|
|
|
|
!
|
|
|
|
! to
|
|
|
|
!
|
2009-07-27 23:28:29 -04:00
|
|
|
! x = y
|
|
|
|
! x = x op z
|
2009-08-05 19:57:46 -04:00
|
|
|
!
|
2009-06-08 22:15:52 -04:00
|
|
|
! We don't bother with ##add, ##add-imm, ##sub-imm or ##mul-imm
|
|
|
|
! since x86 has LEA and IMUL instructions which are effectively
|
|
|
|
! three-operand addition and multiplication, respectively.
|
2008-10-28 05:38:37 -04:00
|
|
|
|
2009-07-27 23:28:29 -04:00
|
|
|
UNION: two-operand-insn
|
|
|
|
##sub
|
|
|
|
##mul
|
|
|
|
##and
|
|
|
|
##and-imm
|
|
|
|
##or
|
|
|
|
##or-imm
|
|
|
|
##xor
|
|
|
|
##xor-imm
|
|
|
|
##shl
|
|
|
|
##shl-imm
|
|
|
|
##shr
|
|
|
|
##shr-imm
|
|
|
|
##sar
|
|
|
|
##sar-imm
|
2009-08-28 20:02:59 -04:00
|
|
|
##min
|
|
|
|
##max
|
2009-09-02 07:22:37 -04:00
|
|
|
##fixnum-add
|
|
|
|
##fixnum-sub
|
|
|
|
##fixnum-mul
|
2009-07-27 23:28:29 -04:00
|
|
|
##add-float
|
|
|
|
##sub-float
|
|
|
|
##mul-float
|
2009-08-28 06:21:16 -04:00
|
|
|
##div-float
|
|
|
|
##min-float
|
2009-09-03 03:33:07 -04:00
|
|
|
##max-float
|
|
|
|
##add-vector
|
|
|
|
##sub-vector
|
|
|
|
##mul-vector
|
|
|
|
##div-vector
|
|
|
|
##min-vector
|
|
|
|
##max-vector ;
|
2009-07-27 23:28:29 -04:00
|
|
|
|
|
|
|
GENERIC: convert-two-operand* ( insn -- )
|
2008-10-28 05:38:37 -04:00
|
|
|
|
2009-07-27 23:28:29 -04:00
|
|
|
: emit-copy ( dst src -- )
|
2009-08-08 05:02:18 -04:00
|
|
|
dup rep-of ##copy ; inline
|
2009-07-27 23:28:29 -04:00
|
|
|
|
2009-08-05 19:57:46 -04:00
|
|
|
M: two-operand-insn convert-two-operand*
|
2009-07-27 23:28:29 -04:00
|
|
|
[ [ dst>> ] [ src1>> ] bi emit-copy ]
|
2009-08-08 21:03:42 -04:00
|
|
|
[
|
|
|
|
dup [ src1>> ] [ src2>> ] bi = [ dup dst>> >>src2 ] when
|
|
|
|
dup dst>> >>src1 ,
|
|
|
|
] bi ;
|
2008-10-28 05:38:37 -04:00
|
|
|
|
|
|
|
M: ##not convert-two-operand*
|
2009-08-05 19:57:46 -04:00
|
|
|
[ [ dst>> ] [ src>> ] bi emit-copy ]
|
|
|
|
[ dup dst>> >>src , ]
|
|
|
|
bi ;
|
2008-10-28 05:38:37 -04:00
|
|
|
|
2009-05-29 14:11:34 -04:00
|
|
|
M: insn convert-two-operand* , ;
|
2008-10-28 05:38:37 -04:00
|
|
|
|
2009-08-02 10:16:21 -04:00
|
|
|
: (convert-two-operand) ( insns -- insns' )
|
|
|
|
dup first kill-vreg-insn? [
|
|
|
|
[ [ convert-two-operand* ] each ] V{ } make
|
|
|
|
] unless ;
|
2009-07-27 23:28:29 -04:00
|
|
|
|
2009-05-29 14:11:34 -04:00
|
|
|
: convert-two-operand ( cfg -- cfg' )
|
2009-07-27 23:28:29 -04:00
|
|
|
two-operand? [ [ (convert-two-operand) ] local-optimization ] when ;
|