mirror of
https://github.com/golang/go
synced 2024-10-05 16:41:21 -06:00
[dev.ssa] cmd/compile/internal/ssa: allow ops to have a default type
Specifying types in rewrites for all subexpressions gets verbose quickly. Allow opcodes to specify a default type which is used when none is supplied explicitly. Provide default types for a few easy opcodes. There are probably more we can do, but this is a good start. Change-Id: Iedc2a1a423cc3e2d4472640433982f9aa76a9f18 Reviewed-on: https://go-review.googlesource.com/14128 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
a0022d9b8c
commit
65677cabfd
@ -43,8 +43,8 @@
|
||||
(Div32u x y) -> (DIVLU x y)
|
||||
(Div16 x y) -> (DIVW x y)
|
||||
(Div16u x y) -> (DIVWU x y)
|
||||
(Div8 x y) -> (DIVW (SignExt8to16 <config.Frontend().TypeInt16()> x) (SignExt8to16 <config.Frontend().TypeInt16()> y))
|
||||
(Div8u x y) -> (DIVWU (ZeroExt8to16 <config.Frontend().TypeUInt16()> x) (ZeroExt8to16 <config.Frontend().TypeUInt16()> y))
|
||||
(Div8 x y) -> (DIVW (SignExt8to16 x) (SignExt8to16 y))
|
||||
(Div8u x y) -> (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
|
||||
|
||||
(Hmul32 x y) -> (HMULL x y)
|
||||
(Hmul32u x y) -> (HMULLU x y)
|
||||
@ -59,8 +59,8 @@
|
||||
(Mod32u x y) -> (MODLU x y)
|
||||
(Mod16 x y) -> (MODW x y)
|
||||
(Mod16u x y) -> (MODWU x y)
|
||||
(Mod8 x y) -> (MODW (SignExt8to16 <config.Frontend().TypeInt16()> x) (SignExt8to16 <config.Frontend().TypeInt16()> y))
|
||||
(Mod8u x y) -> (MODWU (ZeroExt8to16 <config.Frontend().TypeUInt16()> x) (ZeroExt8to16 <config.Frontend().TypeUInt16()> y))
|
||||
(Mod8 x y) -> (MODW (SignExt8to16 x) (SignExt8to16 y))
|
||||
(Mod8u x y) -> (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
|
||||
|
||||
(And64 x y) -> (ANDQ x y)
|
||||
(And32 x y) -> (ANDL x y)
|
||||
@ -127,139 +127,139 @@
|
||||
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
|
||||
// result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
|
||||
// Note: for small shifts we generate 32 bits of mask even when we don't need it all.
|
||||
(Lsh64x64 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPQconst <TypeFlags> [64] y)))
|
||||
(Lsh64x32 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPLconst <TypeFlags> [64] y)))
|
||||
(Lsh64x16 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPWconst <TypeFlags> [64] y)))
|
||||
(Lsh64x8 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPBconst <TypeFlags> [64] y)))
|
||||
(Lsh64x64 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPQconst [64] y)))
|
||||
(Lsh64x32 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPLconst [64] y)))
|
||||
(Lsh64x16 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPWconst [64] y)))
|
||||
(Lsh64x8 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPBconst [64] y)))
|
||||
|
||||
(Lsh32x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst <TypeFlags> [32] y)))
|
||||
(Lsh32x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst <TypeFlags> [32] y)))
|
||||
(Lsh32x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst <TypeFlags> [32] y)))
|
||||
(Lsh32x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst <TypeFlags> [32] y)))
|
||||
(Lsh32x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst [32] y)))
|
||||
(Lsh32x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst [32] y)))
|
||||
(Lsh32x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst [32] y)))
|
||||
(Lsh32x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst [32] y)))
|
||||
|
||||
(Lsh16x64 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPQconst <TypeFlags> [16] y)))
|
||||
(Lsh16x32 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPLconst <TypeFlags> [16] y)))
|
||||
(Lsh16x16 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPWconst <TypeFlags> [16] y)))
|
||||
(Lsh16x8 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPBconst <TypeFlags> [16] y)))
|
||||
(Lsh16x64 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPQconst [16] y)))
|
||||
(Lsh16x32 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPLconst [16] y)))
|
||||
(Lsh16x16 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPWconst [16] y)))
|
||||
(Lsh16x8 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPBconst [16] y)))
|
||||
|
||||
(Lsh8x64 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPQconst <TypeFlags> [8] y)))
|
||||
(Lsh8x32 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPLconst <TypeFlags> [8] y)))
|
||||
(Lsh8x16 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPWconst <TypeFlags> [8] y)))
|
||||
(Lsh8x8 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPBconst <TypeFlags> [8] y)))
|
||||
(Lsh8x64 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPQconst [8] y)))
|
||||
(Lsh8x32 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPLconst [8] y)))
|
||||
(Lsh8x16 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPWconst [8] y)))
|
||||
(Lsh8x8 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPBconst [8] y)))
|
||||
|
||||
(Lrot64 <t> x [c]) -> (ROLQconst <t> [c&63] x)
|
||||
(Lrot32 <t> x [c]) -> (ROLLconst <t> [c&31] x)
|
||||
(Lrot16 <t> x [c]) -> (ROLWconst <t> [c&15] x)
|
||||
(Lrot8 <t> x [c]) -> (ROLBconst <t> [c&7] x)
|
||||
|
||||
(Rsh64Ux64 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPQconst <TypeFlags> [64] y)))
|
||||
(Rsh64Ux32 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPLconst <TypeFlags> [64] y)))
|
||||
(Rsh64Ux16 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPWconst <TypeFlags> [64] y)))
|
||||
(Rsh64Ux8 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPBconst <TypeFlags> [64] y)))
|
||||
(Rsh64Ux64 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPQconst [64] y)))
|
||||
(Rsh64Ux32 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPLconst [64] y)))
|
||||
(Rsh64Ux16 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPWconst [64] y)))
|
||||
(Rsh64Ux8 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPBconst [64] y)))
|
||||
|
||||
(Rsh32Ux64 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPQconst <TypeFlags> [32] y)))
|
||||
(Rsh32Ux32 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPLconst <TypeFlags> [32] y)))
|
||||
(Rsh32Ux16 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPWconst <TypeFlags> [32] y)))
|
||||
(Rsh32Ux8 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst <TypeFlags> [32] y)))
|
||||
(Rsh32Ux64 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPQconst [32] y)))
|
||||
(Rsh32Ux32 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPLconst [32] y)))
|
||||
(Rsh32Ux16 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPWconst [32] y)))
|
||||
(Rsh32Ux8 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst [32] y)))
|
||||
|
||||
(Rsh16Ux64 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPQconst <TypeFlags> [16] y)))
|
||||
(Rsh16Ux32 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPLconst <TypeFlags> [16] y)))
|
||||
(Rsh16Ux16 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPWconst <TypeFlags> [16] y)))
|
||||
(Rsh16Ux8 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst <TypeFlags> [16] y)))
|
||||
(Rsh16Ux64 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPQconst [16] y)))
|
||||
(Rsh16Ux32 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPLconst [16] y)))
|
||||
(Rsh16Ux16 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPWconst [16] y)))
|
||||
(Rsh16Ux8 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst [16] y)))
|
||||
|
||||
(Rsh8Ux64 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPQconst <TypeFlags> [8] y)))
|
||||
(Rsh8Ux32 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPLconst <TypeFlags> [8] y)))
|
||||
(Rsh8Ux16 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPWconst <TypeFlags> [8] y)))
|
||||
(Rsh8Ux8 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst <TypeFlags> [8] y)))
|
||||
(Rsh8Ux64 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPQconst [8] y)))
|
||||
(Rsh8Ux32 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPLconst [8] y)))
|
||||
(Rsh8Ux16 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPWconst [8] y)))
|
||||
(Rsh8Ux8 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst [8] y)))
|
||||
|
||||
// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
|
||||
// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
|
||||
// Note: for small shift widths we generate 32 bits of mask even when we don't need it all.
|
||||
(Rsh64x64 <t> x y) -> (SARQ <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst <TypeFlags> [64] y)))))
|
||||
(Rsh64x32 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst <TypeFlags> [64] y)))))
|
||||
(Rsh64x16 <t> x y) -> (SARQ <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst <TypeFlags> [64] y)))))
|
||||
(Rsh64x8 <t> x y) -> (SARQ <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst <TypeFlags> [64] y)))))
|
||||
(Rsh64x64 <t> x y) -> (SARQ <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [64] y)))))
|
||||
(Rsh64x32 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [64] y)))))
|
||||
(Rsh64x16 <t> x y) -> (SARQ <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [64] y)))))
|
||||
(Rsh64x8 <t> x y) -> (SARQ <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [64] y)))))
|
||||
|
||||
(Rsh32x64 <t> x y) -> (SARL <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst <TypeFlags> [32] y)))))
|
||||
(Rsh32x32 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst <TypeFlags> [32] y)))))
|
||||
(Rsh32x16 <t> x y) -> (SARL <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst <TypeFlags> [32] y)))))
|
||||
(Rsh32x8 <t> x y) -> (SARL <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst <TypeFlags> [32] y)))))
|
||||
(Rsh32x64 <t> x y) -> (SARL <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [32] y)))))
|
||||
(Rsh32x32 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [32] y)))))
|
||||
(Rsh32x16 <t> x y) -> (SARL <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [32] y)))))
|
||||
(Rsh32x8 <t> x y) -> (SARL <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [32] y)))))
|
||||
|
||||
(Rsh16x64 <t> x y) -> (SARW <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst <TypeFlags> [16] y)))))
|
||||
(Rsh16x32 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst <TypeFlags> [16] y)))))
|
||||
(Rsh16x16 <t> x y) -> (SARW <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst <TypeFlags> [16] y)))))
|
||||
(Rsh16x8 <t> x y) -> (SARW <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst <TypeFlags> [16] y)))))
|
||||
(Rsh16x64 <t> x y) -> (SARW <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [16] y)))))
|
||||
(Rsh16x32 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [16] y)))))
|
||||
(Rsh16x16 <t> x y) -> (SARW <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [16] y)))))
|
||||
(Rsh16x8 <t> x y) -> (SARW <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [16] y)))))
|
||||
|
||||
(Rsh8x64 <t> x y) -> (SARB <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst <TypeFlags> [8] y)))))
|
||||
(Rsh8x32 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst <TypeFlags> [8] y)))))
|
||||
(Rsh8x16 <t> x y) -> (SARB <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst <TypeFlags> [8] y)))))
|
||||
(Rsh8x8 <t> x y) -> (SARB <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst <TypeFlags> [8] y)))))
|
||||
(Rsh8x64 <t> x y) -> (SARB <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [8] y)))))
|
||||
(Rsh8x32 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [8] y)))))
|
||||
(Rsh8x16 <t> x y) -> (SARB <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [8] y)))))
|
||||
(Rsh8x8 <t> x y) -> (SARB <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [8] y)))))
|
||||
|
||||
(Less64 x y) -> (SETL (CMPQ <TypeFlags> x y))
|
||||
(Less32 x y) -> (SETL (CMPL <TypeFlags> x y))
|
||||
(Less16 x y) -> (SETL (CMPW <TypeFlags> x y))
|
||||
(Less8 x y) -> (SETL (CMPB <TypeFlags> x y))
|
||||
(Less64U x y) -> (SETB (CMPQ <TypeFlags> x y))
|
||||
(Less32U x y) -> (SETB (CMPL <TypeFlags> x y))
|
||||
(Less16U x y) -> (SETB (CMPW <TypeFlags> x y))
|
||||
(Less8U x y) -> (SETB (CMPB <TypeFlags> x y))
|
||||
(Less64 x y) -> (SETL (CMPQ x y))
|
||||
(Less32 x y) -> (SETL (CMPL x y))
|
||||
(Less16 x y) -> (SETL (CMPW x y))
|
||||
(Less8 x y) -> (SETL (CMPB x y))
|
||||
(Less64U x y) -> (SETB (CMPQ x y))
|
||||
(Less32U x y) -> (SETB (CMPL x y))
|
||||
(Less16U x y) -> (SETB (CMPW x y))
|
||||
(Less8U x y) -> (SETB (CMPB x y))
|
||||
// Use SETGF with reversed operands to dodge NaN case
|
||||
(Less64F x y) -> (SETGF (UCOMISD <TypeFlags> y x))
|
||||
(Less32F x y) -> (SETGF (UCOMISS <TypeFlags> y x))
|
||||
(Less64F x y) -> (SETGF (UCOMISD y x))
|
||||
(Less32F x y) -> (SETGF (UCOMISS y x))
|
||||
|
||||
(Leq64 x y) -> (SETLE (CMPQ <TypeFlags> x y))
|
||||
(Leq32 x y) -> (SETLE (CMPL <TypeFlags> x y))
|
||||
(Leq16 x y) -> (SETLE (CMPW <TypeFlags> x y))
|
||||
(Leq8 x y) -> (SETLE (CMPB <TypeFlags> x y))
|
||||
(Leq64U x y) -> (SETBE (CMPQ <TypeFlags> x y))
|
||||
(Leq32U x y) -> (SETBE (CMPL <TypeFlags> x y))
|
||||
(Leq16U x y) -> (SETBE (CMPW <TypeFlags> x y))
|
||||
(Leq8U x y) -> (SETBE (CMPB <TypeFlags> x y))
|
||||
(Leq64 x y) -> (SETLE (CMPQ x y))
|
||||
(Leq32 x y) -> (SETLE (CMPL x y))
|
||||
(Leq16 x y) -> (SETLE (CMPW x y))
|
||||
(Leq8 x y) -> (SETLE (CMPB x y))
|
||||
(Leq64U x y) -> (SETBE (CMPQ x y))
|
||||
(Leq32U x y) -> (SETBE (CMPL x y))
|
||||
(Leq16U x y) -> (SETBE (CMPW x y))
|
||||
(Leq8U x y) -> (SETBE (CMPB x y))
|
||||
// Use SETGEF with reversed operands to dodge NaN case
|
||||
(Leq64F x y) -> (SETGEF (UCOMISD <TypeFlags> y x))
|
||||
(Leq32F x y) -> (SETGEF (UCOMISS <TypeFlags> y x))
|
||||
(Leq64F x y) -> (SETGEF (UCOMISD y x))
|
||||
(Leq32F x y) -> (SETGEF (UCOMISS y x))
|
||||
|
||||
(Greater64 x y) -> (SETG (CMPQ <TypeFlags> x y))
|
||||
(Greater32 x y) -> (SETG (CMPL <TypeFlags> x y))
|
||||
(Greater16 x y) -> (SETG (CMPW <TypeFlags> x y))
|
||||
(Greater8 x y) -> (SETG (CMPB <TypeFlags> x y))
|
||||
(Greater64U x y) -> (SETA (CMPQ <TypeFlags> x y))
|
||||
(Greater32U x y) -> (SETA (CMPL <TypeFlags> x y))
|
||||
(Greater16U x y) -> (SETA (CMPW <TypeFlags> x y))
|
||||
(Greater8U x y) -> (SETA (CMPB <TypeFlags> x y))
|
||||
(Greater64 x y) -> (SETG (CMPQ x y))
|
||||
(Greater32 x y) -> (SETG (CMPL x y))
|
||||
(Greater16 x y) -> (SETG (CMPW x y))
|
||||
(Greater8 x y) -> (SETG (CMPB x y))
|
||||
(Greater64U x y) -> (SETA (CMPQ x y))
|
||||
(Greater32U x y) -> (SETA (CMPL x y))
|
||||
(Greater16U x y) -> (SETA (CMPW x y))
|
||||
(Greater8U x y) -> (SETA (CMPB x y))
|
||||
// Note Go assembler gets UCOMISx operand order wrong, but it is right here
|
||||
// Bug is accommodated at generation of assembly language.
|
||||
(Greater64F x y) -> (SETGF (UCOMISD <TypeFlags> x y))
|
||||
(Greater32F x y) -> (SETGF (UCOMISS <TypeFlags> x y))
|
||||
(Greater64F x y) -> (SETGF (UCOMISD x y))
|
||||
(Greater32F x y) -> (SETGF (UCOMISS x y))
|
||||
|
||||
(Geq64 x y) -> (SETGE (CMPQ <TypeFlags> x y))
|
||||
(Geq32 x y) -> (SETGE (CMPL <TypeFlags> x y))
|
||||
(Geq16 x y) -> (SETGE (CMPW <TypeFlags> x y))
|
||||
(Geq8 x y) -> (SETGE (CMPB <TypeFlags> x y))
|
||||
(Geq64U x y) -> (SETAE (CMPQ <TypeFlags> x y))
|
||||
(Geq32U x y) -> (SETAE (CMPL <TypeFlags> x y))
|
||||
(Geq16U x y) -> (SETAE (CMPW <TypeFlags> x y))
|
||||
(Geq8U x y) -> (SETAE (CMPB <TypeFlags> x y))
|
||||
(Geq64 x y) -> (SETGE (CMPQ x y))
|
||||
(Geq32 x y) -> (SETGE (CMPL x y))
|
||||
(Geq16 x y) -> (SETGE (CMPW x y))
|
||||
(Geq8 x y) -> (SETGE (CMPB x y))
|
||||
(Geq64U x y) -> (SETAE (CMPQ x y))
|
||||
(Geq32U x y) -> (SETAE (CMPL x y))
|
||||
(Geq16U x y) -> (SETAE (CMPW x y))
|
||||
(Geq8U x y) -> (SETAE (CMPB x y))
|
||||
// Note Go assembler gets UCOMISx operand order wrong, but it is right here
|
||||
// Bug is accommodated at generation of assembly language.
|
||||
(Geq64F x y) -> (SETGEF (UCOMISD <TypeFlags> x y))
|
||||
(Geq32F x y) -> (SETGEF (UCOMISS <TypeFlags> x y))
|
||||
(Geq64F x y) -> (SETGEF (UCOMISD x y))
|
||||
(Geq32F x y) -> (SETGEF (UCOMISS x y))
|
||||
|
||||
(Eq64 x y) -> (SETEQ (CMPQ <TypeFlags> x y))
|
||||
(Eq32 x y) -> (SETEQ (CMPL <TypeFlags> x y))
|
||||
(Eq16 x y) -> (SETEQ (CMPW <TypeFlags> x y))
|
||||
(Eq8 x y) -> (SETEQ (CMPB <TypeFlags> x y))
|
||||
(EqPtr x y) -> (SETEQ (CMPQ <TypeFlags> x y))
|
||||
(Eq64F x y) -> (SETEQF (UCOMISD <TypeFlags> x y))
|
||||
(Eq32F x y) -> (SETEQF (UCOMISS <TypeFlags> x y))
|
||||
(Eq64 x y) -> (SETEQ (CMPQ x y))
|
||||
(Eq32 x y) -> (SETEQ (CMPL x y))
|
||||
(Eq16 x y) -> (SETEQ (CMPW x y))
|
||||
(Eq8 x y) -> (SETEQ (CMPB x y))
|
||||
(EqPtr x y) -> (SETEQ (CMPQ x y))
|
||||
(Eq64F x y) -> (SETEQF (UCOMISD x y))
|
||||
(Eq32F x y) -> (SETEQF (UCOMISS x y))
|
||||
|
||||
(Neq64 x y) -> (SETNE (CMPQ <TypeFlags> x y))
|
||||
(Neq32 x y) -> (SETNE (CMPL <TypeFlags> x y))
|
||||
(Neq16 x y) -> (SETNE (CMPW <TypeFlags> x y))
|
||||
(Neq8 x y) -> (SETNE (CMPB <TypeFlags> x y))
|
||||
(NeqPtr x y) -> (SETNE (CMPQ <TypeFlags> x y))
|
||||
(Neq64F x y) -> (SETNEF (UCOMISD <TypeFlags> x y))
|
||||
(Neq32F x y) -> (SETNEF (UCOMISS <TypeFlags> x y))
|
||||
(Neq64 x y) -> (SETNE (CMPQ x y))
|
||||
(Neq32 x y) -> (SETNE (CMPL x y))
|
||||
(Neq16 x y) -> (SETNE (CMPW x y))
|
||||
(Neq8 x y) -> (SETNE (CMPB x y))
|
||||
(NeqPtr x y) -> (SETNE (CMPQ x y))
|
||||
(Neq64F x y) -> (SETNEF (UCOMISD x y))
|
||||
(Neq32F x y) -> (SETNEF (UCOMISS x y))
|
||||
|
||||
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) -> (MOVQload ptr mem)
|
||||
(Load <t> ptr mem) && is32BitInt(t) -> (MOVLload ptr mem)
|
||||
@ -278,9 +278,9 @@
|
||||
(Store [1] ptr val mem) -> (MOVBstore ptr val mem)
|
||||
|
||||
// checks
|
||||
(IsNonNil p) -> (SETNE (TESTQ <TypeFlags> p p))
|
||||
(IsInBounds idx len) -> (SETB (CMPQ <TypeFlags> idx len))
|
||||
(IsSliceInBounds idx len) -> (SETBE (CMPQ <TypeFlags> idx len))
|
||||
(IsNonNil p) -> (SETNE (TESTQ p p))
|
||||
(IsInBounds idx len) -> (SETB (CMPQ idx len))
|
||||
(IsSliceInBounds idx len) -> (SETBE (CMPQ idx len))
|
||||
|
||||
(PanicNilCheck ptr mem) -> (LoweredPanicNilCheck ptr mem)
|
||||
(PanicIndexCheck mem) -> (LoweredPanicIndexCheck mem)
|
||||
@ -326,7 +326,7 @@
|
||||
(If (SETEQF cmp) yes no) -> (EQF cmp yes no)
|
||||
(If (SETNEF cmp) yes no) -> (EQF cmp yes no)
|
||||
|
||||
(If cond yes no) -> (NE (TESTB <TypeFlags> cond cond) yes no)
|
||||
(If cond yes no) -> (NE (TESTB cond cond) yes no)
|
||||
|
||||
(NE (TESTB (SETL cmp)) yes no) -> (LT cmp yes no)
|
||||
(NE (TESTB (SETLE cmp)) yes no) -> (LE cmp yes no)
|
||||
@ -435,13 +435,13 @@
|
||||
// (SHLW x (MOVWconst [24])), but just in case.
|
||||
|
||||
(CMPQ x (MOVQconst [c])) && is32Bit(c) -> (CMPQconst x [c])
|
||||
(CMPQ (MOVQconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPQconst <TypeFlags> x [c]))
|
||||
(CMPQ (MOVQconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPQconst x [c]))
|
||||
(CMPL x (MOVLconst [c])) -> (CMPLconst x [c])
|
||||
(CMPL (MOVLconst [c]) x) -> (InvertFlags (CMPLconst <TypeFlags> x [c]))
|
||||
(CMPL (MOVLconst [c]) x) -> (InvertFlags (CMPLconst x [c]))
|
||||
(CMPW x (MOVWconst [c])) -> (CMPWconst x [c])
|
||||
(CMPW (MOVWconst [c]) x) -> (InvertFlags (CMPWconst <TypeFlags> x [c]))
|
||||
(CMPW (MOVWconst [c]) x) -> (InvertFlags (CMPWconst x [c]))
|
||||
(CMPB x (MOVBconst [c])) -> (CMPBconst x [c])
|
||||
(CMPB (MOVBconst [c]) x) -> (InvertFlags (CMPBconst <TypeFlags> x [c]))
|
||||
(CMPB (MOVBconst [c]) x) -> (InvertFlags (CMPBconst x [c]))
|
||||
|
||||
// strength reduction
|
||||
(MULQconst [-1] x) -> (NEGQ x)
|
||||
|
@ -241,26 +241,26 @@ func init() {
|
||||
{name: "XORWconst", reg: gp11, asm: "XORW"}, // arg0 ^ auxint
|
||||
{name: "XORBconst", reg: gp11, asm: "XORB"}, // arg0 ^ auxint
|
||||
|
||||
{name: "CMPQ", reg: gp2flags, asm: "CMPQ"}, // arg0 compare to arg1
|
||||
{name: "CMPL", reg: gp2flags, asm: "CMPL"}, // arg0 compare to arg1
|
||||
{name: "CMPW", reg: gp2flags, asm: "CMPW"}, // arg0 compare to arg1
|
||||
{name: "CMPB", reg: gp2flags, asm: "CMPB"}, // arg0 compare to arg1
|
||||
{name: "CMPQconst", reg: gp1flags, asm: "CMPQ"}, // arg0 compare to auxint
|
||||
{name: "CMPLconst", reg: gp1flags, asm: "CMPL"}, // arg0 compare to auxint
|
||||
{name: "CMPWconst", reg: gp1flags, asm: "CMPW"}, // arg0 compare to auxint
|
||||
{name: "CMPBconst", reg: gp1flags, asm: "CMPB"}, // arg0 compare to auxint
|
||||
{name: "CMPQ", reg: gp2flags, asm: "CMPQ", typ: "Flags"}, // arg0 compare to arg1
|
||||
{name: "CMPL", reg: gp2flags, asm: "CMPL", typ: "Flags"}, // arg0 compare to arg1
|
||||
{name: "CMPW", reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
|
||||
{name: "CMPB", reg: gp2flags, asm: "CMPB", typ: "Flags"}, // arg0 compare to arg1
|
||||
{name: "CMPQconst", reg: gp1flags, asm: "CMPQ", typ: "Flags"}, // arg0 compare to auxint
|
||||
{name: "CMPLconst", reg: gp1flags, asm: "CMPL", typ: "Flags"}, // arg0 compare to auxint
|
||||
{name: "CMPWconst", reg: gp1flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to auxint
|
||||
{name: "CMPBconst", reg: gp1flags, asm: "CMPB", typ: "Flags"}, // arg0 compare to auxint
|
||||
|
||||
{name: "UCOMISS", reg: fp2flags, asm: "UCOMISS"}, // arg0 compare to arg1, f32
|
||||
{name: "UCOMISD", reg: fp2flags, asm: "UCOMISD"}, // arg0 compare to arg1, f64
|
||||
{name: "UCOMISS", reg: fp2flags, asm: "UCOMISS", typ: "Flags"}, // arg0 compare to arg1, f32
|
||||
{name: "UCOMISD", reg: fp2flags, asm: "UCOMISD", typ: "Flags"}, // arg0 compare to arg1, f64
|
||||
|
||||
{name: "TESTQ", reg: gp2flags, asm: "TESTQ"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTL", reg: gp2flags, asm: "TESTL"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTW", reg: gp2flags, asm: "TESTW"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTB", reg: gp2flags, asm: "TESTB"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTQconst", reg: gp1flags, asm: "TESTQ"}, // (arg0 & auxint) compare to 0
|
||||
{name: "TESTLconst", reg: gp1flags, asm: "TESTL"}, // (arg0 & auxint) compare to 0
|
||||
{name: "TESTWconst", reg: gp1flags, asm: "TESTW"}, // (arg0 & auxint) compare to 0
|
||||
{name: "TESTBconst", reg: gp1flags, asm: "TESTB"}, // (arg0 & auxint) compare to 0
|
||||
{name: "TESTQ", reg: gp2flags, asm: "TESTQ", typ: "Flags"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTL", reg: gp2flags, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTW", reg: gp2flags, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTB", reg: gp2flags, asm: "TESTB", typ: "Flags"}, // (arg0 & arg1) compare to 0
|
||||
{name: "TESTQconst", reg: gp1flags, asm: "TESTQ", typ: "Flags"}, // (arg0 & auxint) compare to 0
|
||||
{name: "TESTLconst", reg: gp1flags, asm: "TESTL", typ: "Flags"}, // (arg0 & auxint) compare to 0
|
||||
{name: "TESTWconst", reg: gp1flags, asm: "TESTW", typ: "Flags"}, // (arg0 & auxint) compare to 0
|
||||
{name: "TESTBconst", reg: gp1flags, asm: "TESTB", typ: "Flags"}, // (arg0 & auxint) compare to 0
|
||||
|
||||
{name: "SHLQ", reg: gp21shift, asm: "SHLQ"}, // arg0 << arg1, shift amount is mod 64
|
||||
{name: "SHLL", reg: gp21shift, asm: "SHLL"}, // arg0 << arg1, shift amount is mod 32
|
||||
|
@ -65,13 +65,13 @@
|
||||
(EqFat x y) && x.Op == OpConstNil && y.Op != OpConstNil -> (EqFat y x)
|
||||
(NeqFat x y) && x.Op == OpConstNil && y.Op != OpConstNil -> (NeqFat y x)
|
||||
// it suffices to check the first word (backing array for slices, dynamic type for interfaces)
|
||||
(EqFat (Load ptr mem) (ConstNil)) -> (EqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr <config.fe.TypeUintptr()> [0]))
|
||||
(NeqFat (Load ptr mem) (ConstNil)) -> (NeqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr <config.fe.TypeUintptr()> [0]))
|
||||
(EqFat (Load ptr mem) (ConstNil)) -> (EqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr [0]))
|
||||
(NeqFat (Load ptr mem) (ConstNil)) -> (NeqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr [0]))
|
||||
|
||||
// indexing operations
|
||||
// Note: bounds check has already been done
|
||||
(ArrayIndex (Load ptr mem) idx) -> (Load (PtrIndex <v.Type.PtrTo()> ptr idx) mem)
|
||||
(PtrIndex <t> ptr idx) -> (AddPtr ptr (MulPtr <config.fe.TypeUintptr()> idx (ConstPtr <config.fe.TypeUintptr()> [t.Elem().Size()])))
|
||||
(PtrIndex <t> ptr idx) -> (AddPtr ptr (MulPtr idx (ConstPtr [t.Elem().Size()])))
|
||||
(StructSelect [idx] (Load ptr mem)) -> (Load (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
|
||||
|
||||
// complex ops
|
||||
@ -89,7 +89,7 @@
|
||||
(Store [4]
|
||||
(OffPtr <config.fe.TypeFloat32().PtrTo()> [4] dst)
|
||||
imag
|
||||
(Store <TypeMem> [4] dst real mem))
|
||||
(Store [4] dst real mem))
|
||||
|
||||
(Load <t> ptr mem) && t.IsComplex() && t.Size() == 16 ->
|
||||
(ComplexMake
|
||||
@ -102,7 +102,7 @@
|
||||
(Store [8]
|
||||
(OffPtr <config.fe.TypeFloat64().PtrTo()> [8] dst)
|
||||
imag
|
||||
(Store <TypeMem> [8] dst real mem))
|
||||
(Store [8] dst real mem))
|
||||
|
||||
// string ops
|
||||
(StringPtr (StringMake ptr _)) -> ptr
|
||||
@ -110,8 +110,8 @@
|
||||
(ConstString {s}) ->
|
||||
(StringMake
|
||||
(Addr <config.fe.TypeBytePtr()> {config.fe.StringData(s.(string))}
|
||||
(SB <config.fe.TypeUintptr()>))
|
||||
(ConstPtr <config.fe.TypeUintptr()> [int64(len(s.(string)))]))
|
||||
(SB))
|
||||
(ConstPtr [int64(len(s.(string)))]))
|
||||
(Load <t> ptr mem) && t.IsString() ->
|
||||
(StringMake
|
||||
(Load <config.fe.TypeBytePtr()> ptr mem)
|
||||
@ -122,7 +122,7 @@
|
||||
(Store [config.PtrSize]
|
||||
(OffPtr <config.fe.TypeUintptr().PtrTo()> [config.PtrSize] dst)
|
||||
len
|
||||
(Store <TypeMem> [config.PtrSize] dst ptr mem))
|
||||
(Store [config.PtrSize] dst ptr mem))
|
||||
|
||||
// slice ops
|
||||
(SlicePtr (SliceMake ptr _ _ )) -> ptr
|
||||
@ -131,8 +131,8 @@
|
||||
(ConstSlice) ->
|
||||
(SliceMake
|
||||
(ConstNil <config.fe.TypeBytePtr()>)
|
||||
(ConstPtr <config.fe.TypeUintptr()>)
|
||||
(ConstPtr <config.fe.TypeUintptr()>))
|
||||
(ConstPtr [0])
|
||||
(ConstPtr [0]))
|
||||
|
||||
(Load <t> ptr mem) && t.IsSlice() ->
|
||||
(SliceMake
|
||||
@ -147,10 +147,10 @@
|
||||
(Store [config.PtrSize]
|
||||
(OffPtr <config.fe.TypeUintptr().PtrTo()> [2*config.PtrSize] dst)
|
||||
cap
|
||||
(Store <TypeMem> [config.PtrSize]
|
||||
(Store [config.PtrSize]
|
||||
(OffPtr <config.fe.TypeUintptr().PtrTo()> [config.PtrSize] dst)
|
||||
len
|
||||
(Store <TypeMem> [config.PtrSize] dst ptr mem)))
|
||||
(Store [config.PtrSize] dst ptr mem)))
|
||||
|
||||
// interface ops
|
||||
(ITab (IMake itab _)) -> itab
|
||||
@ -169,7 +169,7 @@
|
||||
(Store [config.PtrSize]
|
||||
(OffPtr <config.fe.TypeBytePtr().PtrTo()> [config.PtrSize] dst)
|
||||
data
|
||||
(Store <TypeMem> [config.PtrSize] dst itab mem))
|
||||
(Store [config.PtrSize] dst itab mem))
|
||||
|
||||
// big-object moves (TODO: remove?)
|
||||
(Store [size] dst (Load src mem) mem) && size > config.IntSize -> (Move [size] dst src mem)
|
||||
|
@ -30,7 +30,7 @@ var genericOps = []opData{
|
||||
{name: "Mul16"},
|
||||
{name: "Mul32"},
|
||||
{name: "Mul64"},
|
||||
{name: "MulPtr"}, // MulPtr is used for address calculations
|
||||
{name: "MulPtr", typ: "Uintptr"}, // MulPtr is used for address calculations
|
||||
{name: "Mul32F"},
|
||||
{name: "Mul64F"},
|
||||
|
||||
@ -250,9 +250,9 @@ var genericOps = []opData{
|
||||
{name: "Const64"},
|
||||
{name: "Const32F"},
|
||||
{name: "Const64F"},
|
||||
{name: "ConstPtr"}, // pointer-sized integer constant
|
||||
{name: "ConstInterface"}, // nil interface
|
||||
{name: "ConstSlice"}, // nil slice
|
||||
{name: "ConstPtr", typ: "Uintptr"}, // pointer-sized integer constant
|
||||
{name: "ConstInterface"}, // nil interface
|
||||
{name: "ConstSlice"}, // nil slice
|
||||
// TODO: Const32F, ...
|
||||
|
||||
// Constant-like things
|
||||
@ -264,15 +264,15 @@ var genericOps = []opData{
|
||||
// or *AutoSymbol (arg0=SP).
|
||||
{name: "Addr"}, // Address of a variable. Arg0=SP or SB. Aux identifies the variable.
|
||||
|
||||
{name: "SP"}, // stack pointer
|
||||
{name: "SB"}, // static base pointer (a.k.a. globals pointer)
|
||||
{name: "Func"}, // entry address of a function
|
||||
{name: "SP"}, // stack pointer
|
||||
{name: "SB", typ: "Uintptr"}, // static base pointer (a.k.a. globals pointer)
|
||||
{name: "Func"}, // entry address of a function
|
||||
|
||||
// Memory operations
|
||||
{name: "Load"}, // Load from arg0. arg1=memory
|
||||
{name: "Store"}, // Store arg1 to arg0. arg2=memory, auxint=size. Returns memory.
|
||||
{name: "Move"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size. Returns memory.
|
||||
{name: "Zero"}, // arg0=destptr, arg1=mem, auxint=size. Returns memory.
|
||||
{name: "Load"}, // Load from arg0. arg1=memory
|
||||
{name: "Store", typ: "Mem"}, // Store arg1 to arg0. arg2=memory, auxint=size. Returns memory.
|
||||
{name: "Move"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size. Returns memory.
|
||||
{name: "Zero"}, // arg0=destptr, arg1=mem, auxint=size. Returns memory.
|
||||
|
||||
// Function calls. Arguments to the call have already been written to the stack.
|
||||
// Return values appear on the stack. The method receiver, if any, is treated
|
||||
@ -281,13 +281,13 @@ var genericOps = []opData{
|
||||
{name: "StaticCall"}, // call function aux.(*gc.Sym), arg0=memory. Returns memory.
|
||||
|
||||
// Conversions: signed extensions, zero (unsigned) extensions, truncations
|
||||
{name: "SignExt8to16"},
|
||||
{name: "SignExt8to16", typ: "Int16"},
|
||||
{name: "SignExt8to32"},
|
||||
{name: "SignExt8to64"},
|
||||
{name: "SignExt16to32"},
|
||||
{name: "SignExt16to64"},
|
||||
{name: "SignExt32to64"},
|
||||
{name: "ZeroExt8to16"},
|
||||
{name: "ZeroExt8to16", typ: "UInt16"},
|
||||
{name: "ZeroExt8to32"},
|
||||
{name: "ZeroExt8to64"},
|
||||
{name: "ZeroExt16to32"},
|
||||
|
@ -29,6 +29,7 @@ type opData struct {
|
||||
name string
|
||||
reg regInfo
|
||||
asm string
|
||||
typ string // default result type
|
||||
}
|
||||
|
||||
type blockData struct {
|
||||
|
@ -459,7 +459,24 @@ func genResult0(w io.Writer, arch arch, result string, alloc *int, top bool) str
|
||||
}
|
||||
}
|
||||
if !hasType {
|
||||
log.Fatalf("sub-expression %s must have a type", result)
|
||||
// find default type, if any
|
||||
for _, op := range arch.ops {
|
||||
if op.name != s[0] || op.typ == "" || hasType {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(w, "%s.Type = %s\n", v, typeName(op.typ))
|
||||
hasType = true
|
||||
}
|
||||
for _, op := range genericOps {
|
||||
if op.name != s[0] || op.typ == "" || hasType {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(w, "%s.Type = %s\n", v, typeName(op.typ))
|
||||
hasType = true
|
||||
}
|
||||
}
|
||||
if !hasType {
|
||||
log.Fatalf("sub-expression %s (op=%s) must have a type", result, s[0])
|
||||
}
|
||||
return v
|
||||
}
|
||||
@ -547,6 +564,16 @@ func blockName(name string, arch arch) string {
|
||||
return "Block" + arch.name + name
|
||||
}
|
||||
|
||||
// typeName returns the string to use to generate a type.
|
||||
func typeName(typ string) string {
|
||||
switch typ {
|
||||
case "Flags", "Mem":
|
||||
return "Type" + typ
|
||||
default:
|
||||
return "config.fe.Type" + typ + "()"
|
||||
}
|
||||
}
|
||||
|
||||
// unbalanced returns true if there aren't the same number of ( and ) in the string.
|
||||
func unbalanced(s string) bool {
|
||||
var left, right int
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -300,7 +300,7 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
case OpConstSlice:
|
||||
// match: (ConstSlice)
|
||||
// cond:
|
||||
// result: (SliceMake (ConstNil <config.fe.TypeBytePtr()>) (ConstPtr <config.fe.TypeUintptr()>) (ConstPtr <config.fe.TypeUintptr()>))
|
||||
// result: (SliceMake (ConstNil <config.fe.TypeBytePtr()>) (ConstPtr [0]) (ConstPtr [0]))
|
||||
{
|
||||
v.Op = OpSliceMake
|
||||
v.AuxInt = 0
|
||||
@ -310,20 +310,22 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v0.Type = config.fe.TypeBytePtr()
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpConstPtr, TypeInvalid)
|
||||
v1.AuxInt = 0
|
||||
v1.Type = config.fe.TypeUintptr()
|
||||
v.AddArg(v1)
|
||||
v2 := b.NewValue0(v.Line, OpConstPtr, TypeInvalid)
|
||||
v2.AuxInt = 0
|
||||
v2.Type = config.fe.TypeUintptr()
|
||||
v.AddArg(v2)
|
||||
return true
|
||||
}
|
||||
goto endfd2d8ffcd55eaf8a5092a20c3ae61ba3
|
||||
endfd2d8ffcd55eaf8a5092a20c3ae61ba3:
|
||||
goto endc587abac76a5fd9b1284ba891a178e63
|
||||
endc587abac76a5fd9b1284ba891a178e63:
|
||||
;
|
||||
case OpConstString:
|
||||
// match: (ConstString {s})
|
||||
// cond:
|
||||
// result: (StringMake (Addr <config.fe.TypeBytePtr()> {config.fe.StringData(s.(string))} (SB <config.fe.TypeUintptr()>)) (ConstPtr <config.fe.TypeUintptr()> [int64(len(s.(string)))]))
|
||||
// result: (StringMake (Addr <config.fe.TypeBytePtr()> {config.fe.StringData(s.(string))} (SB)) (ConstPtr [int64(len(s.(string)))]))
|
||||
{
|
||||
s := v.Aux
|
||||
v.Op = OpStringMake
|
||||
@ -338,13 +340,13 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v0.AddArg(v1)
|
||||
v.AddArg(v0)
|
||||
v2 := b.NewValue0(v.Line, OpConstPtr, TypeInvalid)
|
||||
v2.Type = config.fe.TypeUintptr()
|
||||
v2.AuxInt = int64(len(s.(string)))
|
||||
v2.Type = config.fe.TypeUintptr()
|
||||
v.AddArg(v2)
|
||||
return true
|
||||
}
|
||||
goto end51a3d96f2d304db9a52f36ee6b29c14e
|
||||
end51a3d96f2d304db9a52f36ee6b29c14e:
|
||||
goto end2eb756398dd4c6b6d126012a26284c89
|
||||
end2eb756398dd4c6b6d126012a26284c89:
|
||||
;
|
||||
case OpEq16:
|
||||
// match: (Eq16 x x)
|
||||
@ -445,15 +447,15 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
;
|
||||
// match: (EqFat (Load ptr mem) (ConstNil))
|
||||
// cond:
|
||||
// result: (EqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr <config.fe.TypeUintptr()> [0]))
|
||||
// result: (EqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr [0]))
|
||||
{
|
||||
if v.Args[0].Op != OpLoad {
|
||||
goto ende10070e5ddd3dc059674d25ccc6a63b5
|
||||
goto end6f10fb57a906a2c23667c770acb6abf9
|
||||
}
|
||||
ptr := v.Args[0].Args[0]
|
||||
mem := v.Args[0].Args[1]
|
||||
if v.Args[1].Op != OpConstNil {
|
||||
goto ende10070e5ddd3dc059674d25ccc6a63b5
|
||||
goto end6f10fb57a906a2c23667c770acb6abf9
|
||||
}
|
||||
v.Op = OpEqPtr
|
||||
v.AuxInt = 0
|
||||
@ -465,13 +467,13 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpConstPtr, TypeInvalid)
|
||||
v1.Type = config.fe.TypeUintptr()
|
||||
v1.AuxInt = 0
|
||||
v1.Type = config.fe.TypeUintptr()
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
goto ende10070e5ddd3dc059674d25ccc6a63b5
|
||||
ende10070e5ddd3dc059674d25ccc6a63b5:
|
||||
goto end6f10fb57a906a2c23667c770acb6abf9
|
||||
end6f10fb57a906a2c23667c770acb6abf9:
|
||||
;
|
||||
case OpIData:
|
||||
// match: (IData (IMake _ data))
|
||||
@ -928,15 +930,15 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
;
|
||||
// match: (NeqFat (Load ptr mem) (ConstNil))
|
||||
// cond:
|
||||
// result: (NeqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr <config.fe.TypeUintptr()> [0]))
|
||||
// result: (NeqPtr (Load <config.fe.TypeUintptr()> ptr mem) (ConstPtr [0]))
|
||||
{
|
||||
if v.Args[0].Op != OpLoad {
|
||||
goto end423eea941d60473e73140e25f5818bfb
|
||||
goto end3ffd7685735a83eaee8dc2577ae89d79
|
||||
}
|
||||
ptr := v.Args[0].Args[0]
|
||||
mem := v.Args[0].Args[1]
|
||||
if v.Args[1].Op != OpConstNil {
|
||||
goto end423eea941d60473e73140e25f5818bfb
|
||||
goto end3ffd7685735a83eaee8dc2577ae89d79
|
||||
}
|
||||
v.Op = OpNeqPtr
|
||||
v.AuxInt = 0
|
||||
@ -948,13 +950,13 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpConstPtr, TypeInvalid)
|
||||
v1.Type = config.fe.TypeUintptr()
|
||||
v1.AuxInt = 0
|
||||
v1.Type = config.fe.TypeUintptr()
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
goto end423eea941d60473e73140e25f5818bfb
|
||||
end423eea941d60473e73140e25f5818bfb:
|
||||
goto end3ffd7685735a83eaee8dc2577ae89d79
|
||||
end3ffd7685735a83eaee8dc2577ae89d79:
|
||||
;
|
||||
case OpOr16:
|
||||
// match: (Or16 x x)
|
||||
@ -1039,7 +1041,7 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
case OpPtrIndex:
|
||||
// match: (PtrIndex <t> ptr idx)
|
||||
// cond:
|
||||
// result: (AddPtr ptr (MulPtr <config.fe.TypeUintptr()> idx (ConstPtr <config.fe.TypeUintptr()> [t.Elem().Size()])))
|
||||
// result: (AddPtr ptr (MulPtr idx (ConstPtr [t.Elem().Size()])))
|
||||
{
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
@ -1050,17 +1052,17 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v.resetArgs()
|
||||
v.AddArg(ptr)
|
||||
v0 := b.NewValue0(v.Line, OpMulPtr, TypeInvalid)
|
||||
v0.Type = config.fe.TypeUintptr()
|
||||
v0.AddArg(idx)
|
||||
v1 := b.NewValue0(v.Line, OpConstPtr, TypeInvalid)
|
||||
v1.Type = config.fe.TypeUintptr()
|
||||
v1.AuxInt = t.Elem().Size()
|
||||
v1.Type = config.fe.TypeUintptr()
|
||||
v0.AddArg(v1)
|
||||
v0.Type = config.fe.TypeUintptr()
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
goto end1e1c5ef80c11231f89a5439cdda98359
|
||||
end1e1c5ef80c11231f89a5439cdda98359:
|
||||
goto end502555083d57a877982955070cda7530
|
||||
end502555083d57a877982955070cda7530:
|
||||
;
|
||||
case OpSliceCap:
|
||||
// match: (SliceCap (SliceMake _ _ cap))
|
||||
@ -1125,14 +1127,14 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
case OpStore:
|
||||
// match: (Store [8] dst (ComplexMake real imag) mem)
|
||||
// cond:
|
||||
// result: (Store [4] (OffPtr <config.fe.TypeFloat32().PtrTo()> [4] dst) imag (Store <TypeMem> [4] dst real mem))
|
||||
// result: (Store [4] (OffPtr <config.fe.TypeFloat32().PtrTo()> [4] dst) imag (Store [4] dst real mem))
|
||||
{
|
||||
if v.AuxInt != 8 {
|
||||
goto endba187c049aa71488994c8a2eb3453045
|
||||
goto endced898cb0a165662afe48ea44ad3318a
|
||||
}
|
||||
dst := v.Args[0]
|
||||
if v.Args[1].Op != OpComplexMake {
|
||||
goto endba187c049aa71488994c8a2eb3453045
|
||||
goto endced898cb0a165662afe48ea44ad3318a
|
||||
}
|
||||
real := v.Args[1].Args[0]
|
||||
imag := v.Args[1].Args[1]
|
||||
@ -1149,27 +1151,27 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v.AddArg(v0)
|
||||
v.AddArg(imag)
|
||||
v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
|
||||
v1.Type = TypeMem
|
||||
v1.AuxInt = 4
|
||||
v1.AddArg(dst)
|
||||
v1.AddArg(real)
|
||||
v1.AddArg(mem)
|
||||
v1.Type = TypeMem
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
goto endba187c049aa71488994c8a2eb3453045
|
||||
endba187c049aa71488994c8a2eb3453045:
|
||||
goto endced898cb0a165662afe48ea44ad3318a
|
||||
endced898cb0a165662afe48ea44ad3318a:
|
||||
;
|
||||
// match: (Store [16] dst (ComplexMake real imag) mem)
|
||||
// cond:
|
||||
// result: (Store [8] (OffPtr <config.fe.TypeFloat64().PtrTo()> [8] dst) imag (Store <TypeMem> [8] dst real mem))
|
||||
// result: (Store [8] (OffPtr <config.fe.TypeFloat64().PtrTo()> [8] dst) imag (Store [8] dst real mem))
|
||||
{
|
||||
if v.AuxInt != 16 {
|
||||
goto end4df4c826201cf51af245d6b89de00589
|
||||
goto end3851a482d7bd37a93c4d81581e85b3ab
|
||||
}
|
||||
dst := v.Args[0]
|
||||
if v.Args[1].Op != OpComplexMake {
|
||||
goto end4df4c826201cf51af245d6b89de00589
|
||||
goto end3851a482d7bd37a93c4d81581e85b3ab
|
||||
}
|
||||
real := v.Args[1].Args[0]
|
||||
imag := v.Args[1].Args[1]
|
||||
@ -1186,27 +1188,27 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v.AddArg(v0)
|
||||
v.AddArg(imag)
|
||||
v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
|
||||
v1.Type = TypeMem
|
||||
v1.AuxInt = 8
|
||||
v1.AddArg(dst)
|
||||
v1.AddArg(real)
|
||||
v1.AddArg(mem)
|
||||
v1.Type = TypeMem
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
goto end4df4c826201cf51af245d6b89de00589
|
||||
end4df4c826201cf51af245d6b89de00589:
|
||||
goto end3851a482d7bd37a93c4d81581e85b3ab
|
||||
end3851a482d7bd37a93c4d81581e85b3ab:
|
||||
;
|
||||
// match: (Store [2*config.PtrSize] dst (StringMake ptr len) mem)
|
||||
// cond:
|
||||
// result: (Store [config.PtrSize] (OffPtr <config.fe.TypeUintptr().PtrTo()> [config.PtrSize] dst) len (Store <TypeMem> [config.PtrSize] dst ptr mem))
|
||||
// result: (Store [config.PtrSize] (OffPtr <config.fe.TypeUintptr().PtrTo()> [config.PtrSize] dst) len (Store [config.PtrSize] dst ptr mem))
|
||||
{
|
||||
if v.AuxInt != 2*config.PtrSize {
|
||||
goto end25ae4fc3dc01583a4adc45067d49940a
|
||||
goto end12abe4021d24e76ed56d64b18730bffb
|
||||
}
|
||||
dst := v.Args[0]
|
||||
if v.Args[1].Op != OpStringMake {
|
||||
goto end25ae4fc3dc01583a4adc45067d49940a
|
||||
goto end12abe4021d24e76ed56d64b18730bffb
|
||||
}
|
||||
ptr := v.Args[1].Args[0]
|
||||
len := v.Args[1].Args[1]
|
||||
@ -1223,27 +1225,27 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v.AddArg(v0)
|
||||
v.AddArg(len)
|
||||
v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
|
||||
v1.Type = TypeMem
|
||||
v1.AuxInt = config.PtrSize
|
||||
v1.AddArg(dst)
|
||||
v1.AddArg(ptr)
|
||||
v1.AddArg(mem)
|
||||
v1.Type = TypeMem
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
goto end25ae4fc3dc01583a4adc45067d49940a
|
||||
end25ae4fc3dc01583a4adc45067d49940a:
|
||||
goto end12abe4021d24e76ed56d64b18730bffb
|
||||
end12abe4021d24e76ed56d64b18730bffb:
|
||||
;
|
||||
// match: (Store [3*config.PtrSize] dst (SliceMake ptr len cap) mem)
|
||||
// cond:
|
||||
// result: (Store [config.PtrSize] (OffPtr <config.fe.TypeUintptr().PtrTo()> [2*config.PtrSize] dst) cap (Store <TypeMem> [config.PtrSize] (OffPtr <config.fe.TypeUintptr().PtrTo()> [config.PtrSize] dst) len (Store <TypeMem> [config.PtrSize] dst ptr mem)))
|
||||
// result: (Store [config.PtrSize] (OffPtr <config.fe.TypeUintptr().PtrTo()> [2*config.PtrSize] dst) cap (Store [config.PtrSize] (OffPtr <config.fe.TypeUintptr().PtrTo()> [config.PtrSize] dst) len (Store [config.PtrSize] dst ptr mem)))
|
||||
{
|
||||
if v.AuxInt != 3*config.PtrSize {
|
||||
goto end39ab85d51c8cd7f5d54e3eea4fb79a96
|
||||
goto end7498d25e17db5398cf073a8590e35cc2
|
||||
}
|
||||
dst := v.Args[0]
|
||||
if v.Args[1].Op != OpSliceMake {
|
||||
goto end39ab85d51c8cd7f5d54e3eea4fb79a96
|
||||
goto end7498d25e17db5398cf073a8590e35cc2
|
||||
}
|
||||
ptr := v.Args[1].Args[0]
|
||||
len := v.Args[1].Args[1]
|
||||
@ -1261,7 +1263,6 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v.AddArg(v0)
|
||||
v.AddArg(cap)
|
||||
v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
|
||||
v1.Type = TypeMem
|
||||
v1.AuxInt = config.PtrSize
|
||||
v2 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
|
||||
v2.Type = config.fe.TypeUintptr().PtrTo()
|
||||
@ -1270,28 +1271,29 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v1.AddArg(v2)
|
||||
v1.AddArg(len)
|
||||
v3 := b.NewValue0(v.Line, OpStore, TypeInvalid)
|
||||
v3.Type = TypeMem
|
||||
v3.AuxInt = config.PtrSize
|
||||
v3.AddArg(dst)
|
||||
v3.AddArg(ptr)
|
||||
v3.AddArg(mem)
|
||||
v3.Type = TypeMem
|
||||
v1.AddArg(v3)
|
||||
v1.Type = TypeMem
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
goto end39ab85d51c8cd7f5d54e3eea4fb79a96
|
||||
end39ab85d51c8cd7f5d54e3eea4fb79a96:
|
||||
goto end7498d25e17db5398cf073a8590e35cc2
|
||||
end7498d25e17db5398cf073a8590e35cc2:
|
||||
;
|
||||
// match: (Store [2*config.PtrSize] dst (IMake itab data) mem)
|
||||
// cond:
|
||||
// result: (Store [config.PtrSize] (OffPtr <config.fe.TypeBytePtr().PtrTo()> [config.PtrSize] dst) data (Store <TypeMem> [config.PtrSize] dst itab mem))
|
||||
// result: (Store [config.PtrSize] (OffPtr <config.fe.TypeBytePtr().PtrTo()> [config.PtrSize] dst) data (Store [config.PtrSize] dst itab mem))
|
||||
{
|
||||
if v.AuxInt != 2*config.PtrSize {
|
||||
goto end63b77ae78d92c05d496202e8b6b96ff3
|
||||
goto endaa801a871178ae3256b3f6f5d9f13514
|
||||
}
|
||||
dst := v.Args[0]
|
||||
if v.Args[1].Op != OpIMake {
|
||||
goto end63b77ae78d92c05d496202e8b6b96ff3
|
||||
goto endaa801a871178ae3256b3f6f5d9f13514
|
||||
}
|
||||
itab := v.Args[1].Args[0]
|
||||
data := v.Args[1].Args[1]
|
||||
@ -1308,16 +1310,16 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
||||
v.AddArg(v0)
|
||||
v.AddArg(data)
|
||||
v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
|
||||
v1.Type = TypeMem
|
||||
v1.AuxInt = config.PtrSize
|
||||
v1.AddArg(dst)
|
||||
v1.AddArg(itab)
|
||||
v1.AddArg(mem)
|
||||
v1.Type = TypeMem
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
goto end63b77ae78d92c05d496202e8b6b96ff3
|
||||
end63b77ae78d92c05d496202e8b6b96ff3:
|
||||
goto endaa801a871178ae3256b3f6f5d9f13514
|
||||
endaa801a871178ae3256b3f6f5d9f13514:
|
||||
;
|
||||
// match: (Store [size] dst (Load src mem) mem)
|
||||
// cond: size > config.IntSize
|
||||
|
Loading…
Reference in New Issue
Block a user