Commit 369f4f5d authored by Keith Randall's avatar Keith Randall

cmd/compile: regalloc of two address instructions

x86 has a lot of instructions that require the output to be in the same
register as one of the inputs.  When allocating the output register,
allocate the same register as the input if it is available.

Improves the performance of golang.org/x/crypto/sha3 by
10% (from 6% slower than 1.6 to 4% faster).

Fixes #14745

Change-Id: I4d81785240c9368e4dc75107b45c959d200df8e6
Reviewed-on: https://go-review.googlesource.com/20488Reviewed-by: default avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 157f0698
......@@ -144,14 +144,14 @@ func init() {
// TODO: 2-address instructions. Mark ops as needing matching input/output regs.
var AMD64ops = []opData{
// fp ops
{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS"}, // fp32 add
{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD"}, // fp64 add
{name: "SUBSS", argLength: 2, reg: fp21x15, asm: "SUBSS"}, // fp32 sub
{name: "SUBSD", argLength: 2, reg: fp21x15, asm: "SUBSD"}, // fp64 sub
{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS"}, // fp32 mul
{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD"}, // fp64 mul
{name: "DIVSS", argLength: 2, reg: fp21x15, asm: "DIVSS"}, // fp32 div
{name: "DIVSD", argLength: 2, reg: fp21x15, asm: "DIVSD"}, // fp64 div
{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS", commutative: true, resultInArg0: true}, // fp32 add
{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD", commutative: true, resultInArg0: true}, // fp64 add
{name: "SUBSS", argLength: 2, reg: fp21x15, asm: "SUBSS", resultInArg0: true}, // fp32 sub
{name: "SUBSD", argLength: 2, reg: fp21x15, asm: "SUBSD", resultInArg0: true}, // fp64 sub
{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS", commutative: true, resultInArg0: true}, // fp32 mul
{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD", commutative: true, resultInArg0: true}, // fp64 mul
{name: "DIVSS", argLength: 2, reg: fp21x15, asm: "DIVSS", resultInArg0: true}, // fp32 div
{name: "DIVSD", argLength: 2, reg: fp21x15, asm: "DIVSD", resultInArg0: true}, // fp64 div
{name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff"}, // fp32 load
{name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff"}, // fp64 load
......@@ -166,32 +166,32 @@ func init() {
{name: "MOVSDstoreidx8", argLength: 4, reg: fpstoreidx, asm: "MOVSD", aux: "SymOff"}, // fp64 indexed by 8i store
// binary ops
{name: "ADDQ", argLength: 2, reg: gp21, asm: "ADDQ"}, // arg0 + arg1
{name: "ADDL", argLength: 2, reg: gp21, asm: "ADDL"}, // arg0 + arg1
{name: "ADDW", argLength: 2, reg: gp21, asm: "ADDL"}, // arg0 + arg1
{name: "ADDB", argLength: 2, reg: gp21, asm: "ADDL"}, // arg0 + arg1
{name: "ADDQconst", argLength: 1, reg: gp11, asm: "ADDQ", aux: "Int64", typ: "UInt64"}, // arg0 + auxint
{name: "ADDLconst", argLength: 1, reg: gp11, asm: "ADDL", aux: "Int32"}, // arg0 + auxint
{name: "ADDWconst", argLength: 1, reg: gp11, asm: "ADDL", aux: "Int16"}, // arg0 + auxint
{name: "ADDBconst", argLength: 1, reg: gp11, asm: "ADDL", aux: "Int8"}, // arg0 + auxint
{name: "SUBQ", argLength: 2, reg: gp21, asm: "SUBQ"}, // arg0 - arg1
{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL"}, // arg0 - arg1
{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBL"}, // arg0 - arg1
{name: "SUBB", argLength: 2, reg: gp21, asm: "SUBL"}, // arg0 - arg1
{name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int64"}, // arg0 - auxint
{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32"}, // arg0 - auxint
{name: "SUBWconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int16"}, // arg0 - auxint
{name: "SUBBconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int8"}, // arg0 - auxint
{name: "MULQ", argLength: 2, reg: gp21, asm: "IMULQ"}, // arg0 * arg1
{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL"}, // arg0 * arg1
{name: "MULW", argLength: 2, reg: gp21, asm: "IMULW"}, // arg0 * arg1
{name: "MULB", argLength: 2, reg: gp21, asm: "IMULW"}, // arg0 * arg1
{name: "MULQconst", argLength: 1, reg: gp11, asm: "IMULQ", aux: "Int64"}, // arg0 * auxint
{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMULL", aux: "Int32"}, // arg0 * auxint
{name: "MULWconst", argLength: 1, reg: gp11, asm: "IMULW", aux: "Int16"}, // arg0 * auxint
{name: "MULBconst", argLength: 1, reg: gp11, asm: "IMULW", aux: "Int8"}, // arg0 * auxint
{name: "ADDQ", argLength: 2, reg: gp21, asm: "ADDQ", commutative: true, resultInArg0: true}, // arg0 + arg1
{name: "ADDL", argLength: 2, reg: gp21, asm: "ADDL", commutative: true, resultInArg0: true}, // arg0 + arg1
{name: "ADDW", argLength: 2, reg: gp21, asm: "ADDL", commutative: true, resultInArg0: true}, // arg0 + arg1
{name: "ADDB", argLength: 2, reg: gp21, asm: "ADDL", commutative: true, resultInArg0: true}, // arg0 + arg1
{name: "ADDQconst", argLength: 1, reg: gp11, asm: "ADDQ", aux: "Int64", resultInArg0: true, typ: "UInt64"}, // arg0 + auxint
{name: "ADDLconst", argLength: 1, reg: gp11, asm: "ADDL", aux: "Int32", resultInArg0: true}, // arg0 + auxint
{name: "ADDWconst", argLength: 1, reg: gp11, asm: "ADDL", aux: "Int16", resultInArg0: true}, // arg0 + auxint
{name: "ADDBconst", argLength: 1, reg: gp11, asm: "ADDL", aux: "Int8", resultInArg0: true}, // arg0 + auxint
{name: "SUBQ", argLength: 2, reg: gp21, asm: "SUBQ", resultInArg0: true}, // arg0 - arg1
{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true}, // arg0 - arg1
{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true}, // arg0 - arg1
{name: "SUBB", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true}, // arg0 - arg1
{name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int64", resultInArg0: true}, // arg0 - auxint
{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true}, // arg0 - auxint
{name: "SUBWconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int16", resultInArg0: true}, // arg0 - auxint
{name: "SUBBconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int8", resultInArg0: true}, // arg0 - auxint
{name: "MULQ", argLength: 2, reg: gp21, asm: "IMULQ", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULW", argLength: 2, reg: gp21, asm: "IMULW", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULB", argLength: 2, reg: gp21, asm: "IMULW", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULQconst", argLength: 1, reg: gp11, asm: "IMULQ", aux: "Int64", resultInArg0: true}, // arg0 * auxint
{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMULL", aux: "Int32", resultInArg0: true}, // arg0 * auxint
{name: "MULWconst", argLength: 1, reg: gp11, asm: "IMULW", aux: "Int16", resultInArg0: true}, // arg0 * auxint
{name: "MULBconst", argLength: 1, reg: gp11, asm: "IMULW", aux: "Int8", resultInArg0: true}, // arg0 * auxint
{name: "HMULQ", argLength: 2, reg: gp11hmul, asm: "IMULQ"}, // (arg0 * arg1) >> width
{name: "HMULL", argLength: 2, reg: gp11hmul, asm: "IMULL"}, // (arg0 * arg1) >> width
......@@ -202,7 +202,7 @@ func init() {
{name: "HMULWU", argLength: 2, reg: gp11hmul, asm: "MULW"}, // (arg0 * arg1) >> width
{name: "HMULBU", argLength: 2, reg: gp11hmul, asm: "MULB"}, // (arg0 * arg1) >> width
{name: "AVGQU", argLength: 2, reg: gp21}, // (arg0 + arg1) / 2 as unsigned, all 64 result bits
{name: "AVGQU", argLength: 2, reg: gp21, commutative: true, resultInArg0: true}, // (arg0 + arg1) / 2 as unsigned, all 64 result bits
{name: "DIVQ", argLength: 2, reg: gp11div, asm: "IDIVQ"}, // arg0 / arg1
{name: "DIVL", argLength: 2, reg: gp11div, asm: "IDIVL"}, // arg0 / arg1
......@@ -218,32 +218,32 @@ func init() {
{name: "MODLU", argLength: 2, reg: gp11mod, asm: "DIVL"}, // arg0 % arg1
{name: "MODWU", argLength: 2, reg: gp11mod, asm: "DIVW"}, // arg0 % arg1
{name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ"}, // arg0 & arg1
{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL"}, // arg0 & arg1
{name: "ANDW", argLength: 2, reg: gp21, asm: "ANDL"}, // arg0 & arg1
{name: "ANDB", argLength: 2, reg: gp21, asm: "ANDL"}, // arg0 & arg1
{name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int64"}, // arg0 & auxint
{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32"}, // arg0 & auxint
{name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int16"}, // arg0 & auxint
{name: "ANDBconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int8"}, // arg0 & auxint
{name: "ORQ", argLength: 2, reg: gp21, asm: "ORQ"}, // arg0 | arg1
{name: "ORL", argLength: 2, reg: gp21, asm: "ORL"}, // arg0 | arg1
{name: "ORW", argLength: 2, reg: gp21, asm: "ORL"}, // arg0 | arg1
{name: "ORB", argLength: 2, reg: gp21, asm: "ORL"}, // arg0 | arg1
{name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int64"}, // arg0 | auxint
{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32"}, // arg0 | auxint
{name: "ORWconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int16"}, // arg0 | auxint
{name: "ORBconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int8"}, // arg0 | auxint
{name: "XORQ", argLength: 2, reg: gp21, asm: "XORQ"}, // arg0 ^ arg1
{name: "XORL", argLength: 2, reg: gp21, asm: "XORL"}, // arg0 ^ arg1
{name: "XORW", argLength: 2, reg: gp21, asm: "XORL"}, // arg0 ^ arg1
{name: "XORB", argLength: 2, reg: gp21, asm: "XORL"}, // arg0 ^ arg1
{name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int64"}, // arg0 ^ auxint
{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32"}, // arg0 ^ auxint
{name: "XORWconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int16"}, // arg0 ^ auxint
{name: "XORBconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int8"}, // arg0 ^ auxint
{name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDW", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDB", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int64", resultInArg0: true}, // arg0 & auxint
{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true}, // arg0 & auxint
{name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int16", resultInArg0: true}, // arg0 & auxint
{name: "ANDBconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int8", resultInArg0: true}, // arg0 & auxint
{name: "ORQ", argLength: 2, reg: gp21, asm: "ORQ", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORW", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORB", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int64", resultInArg0: true}, // arg0 | auxint
{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true}, // arg0 | auxint
{name: "ORWconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int16", resultInArg0: true}, // arg0 | auxint
{name: "ORBconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int8", resultInArg0: true}, // arg0 | auxint
{name: "XORQ", argLength: 2, reg: gp21, asm: "XORQ", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORW", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORB", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int64", resultInArg0: true}, // arg0 ^ auxint
{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true}, // arg0 ^ auxint
{name: "XORWconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int16", resultInArg0: true}, // arg0 ^ auxint
{name: "XORBconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int8", resultInArg0: true}, // arg0 ^ auxint
{name: "CMPQ", argLength: 2, reg: gp2flags, asm: "CMPQ", typ: "Flags"}, // arg0 compare to arg1
{name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"}, // arg0 compare to arg1
......@@ -266,49 +266,49 @@ func init() {
{name: "TESTWconst", argLength: 1, reg: gp1flags, asm: "TESTW", typ: "Flags", aux: "Int16"}, // (arg0 & auxint) compare to 0
{name: "TESTBconst", argLength: 1, reg: gp1flags, asm: "TESTB", typ: "Flags", aux: "Int8"}, // (arg0 & auxint) compare to 0
{name: "SHLQ", argLength: 2, reg: gp21shift, asm: "SHLQ"}, // arg0 << arg1, shift amount is mod 64
{name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL"}, // arg0 << arg1, shift amount is mod 32
{name: "SHLW", argLength: 2, reg: gp21shift, asm: "SHLL"}, // arg0 << arg1, shift amount is mod 32
{name: "SHLB", argLength: 2, reg: gp21shift, asm: "SHLL"}, // arg0 << arg1, shift amount is mod 32
{name: "SHLQconst", argLength: 1, reg: gp11, asm: "SHLQ", aux: "Int64"}, // arg0 << auxint, shift amount 0-63
{name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int32"}, // arg0 << auxint, shift amount 0-31
{name: "SHLWconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int16"}, // arg0 << auxint, shift amount 0-31
{name: "SHLBconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int8"}, // arg0 << auxint, shift amount 0-31
{name: "SHLQ", argLength: 2, reg: gp21shift, asm: "SHLQ", resultInArg0: true}, // arg0 << arg1, shift amount is mod 64
{name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true}, // arg0 << arg1, shift amount is mod 32
{name: "SHLW", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true}, // arg0 << arg1, shift amount is mod 32
{name: "SHLB", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true}, // arg0 << arg1, shift amount is mod 32
{name: "SHLQconst", argLength: 1, reg: gp11, asm: "SHLQ", aux: "Int64", resultInArg0: true}, // arg0 << auxint, shift amount 0-63
{name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int32", resultInArg0: true}, // arg0 << auxint, shift amount 0-31
{name: "SHLWconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int16", resultInArg0: true}, // arg0 << auxint, shift amount 0-31
{name: "SHLBconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int8", resultInArg0: true}, // arg0 << auxint, shift amount 0-31
// Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!
{name: "SHRQ", argLength: 2, reg: gp21shift, asm: "SHRQ"}, // unsigned arg0 >> arg1, shift amount is mod 64
{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL"}, // unsigned arg0 >> arg1, shift amount is mod 32
{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW"}, // unsigned arg0 >> arg1, shift amount is mod 32
{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB"}, // unsigned arg0 >> arg1, shift amount is mod 32
{name: "SHRQconst", argLength: 1, reg: gp11, asm: "SHRQ", aux: "Int64"}, // unsigned arg0 >> auxint, shift amount 0-63
{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int32"}, // unsigned arg0 >> auxint, shift amount 0-31
{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16"}, // unsigned arg0 >> auxint, shift amount 0-31
{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8"}, // unsigned arg0 >> auxint, shift amount 0-31
{name: "SARQ", argLength: 2, reg: gp21shift, asm: "SARQ"}, // signed arg0 >> arg1, shift amount is mod 64
{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL"}, // signed arg0 >> arg1, shift amount is mod 32
{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW"}, // signed arg0 >> arg1, shift amount is mod 32
{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB"}, // signed arg0 >> arg1, shift amount is mod 32
{name: "SARQconst", argLength: 1, reg: gp11, asm: "SARQ", aux: "Int64"}, // signed arg0 >> auxint, shift amount 0-63
{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int32"}, // signed arg0 >> auxint, shift amount 0-31
{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16"}, // signed arg0 >> auxint, shift amount 0-31
{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8"}, // signed arg0 >> auxint, shift amount 0-31
{name: "ROLQconst", argLength: 1, reg: gp11, asm: "ROLQ", aux: "Int64"}, // arg0 rotate left auxint, rotate amount 0-63
{name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int32"}, // arg0 rotate left auxint, rotate amount 0-31
{name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int16"}, // arg0 rotate left auxint, rotate amount 0-15
{name: "ROLBconst", argLength: 1, reg: gp11, asm: "ROLB", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-7
{name: "SHRQ", argLength: 2, reg: gp21shift, asm: "SHRQ", resultInArg0: true}, // unsigned arg0 >> arg1, shift amount is mod 64
{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL", resultInArg0: true}, // unsigned arg0 >> arg1, shift amount is mod 32
{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true}, // unsigned arg0 >> arg1, shift amount is mod 32
{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true}, // unsigned arg0 >> arg1, shift amount is mod 32
{name: "SHRQconst", argLength: 1, reg: gp11, asm: "SHRQ", aux: "Int64", resultInArg0: true}, // unsigned arg0 >> auxint, shift amount 0-63
{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int32", resultInArg0: true}, // unsigned arg0 >> auxint, shift amount 0-31
{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16", resultInArg0: true}, // unsigned arg0 >> auxint, shift amount 0-31
{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true}, // unsigned arg0 >> auxint, shift amount 0-31
{name: "SARQ", argLength: 2, reg: gp21shift, asm: "SARQ", resultInArg0: true}, // signed arg0 >> arg1, shift amount is mod 64
{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true}, // signed arg0 >> arg1, shift amount is mod 32
{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true}, // signed arg0 >> arg1, shift amount is mod 32
{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true}, // signed arg0 >> arg1, shift amount is mod 32
{name: "SARQconst", argLength: 1, reg: gp11, asm: "SARQ", aux: "Int64", resultInArg0: true}, // signed arg0 >> auxint, shift amount 0-63
{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int32", resultInArg0: true}, // signed arg0 >> auxint, shift amount 0-31
{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16", resultInArg0: true}, // signed arg0 >> auxint, shift amount 0-31
{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true}, // signed arg0 >> auxint, shift amount 0-31
{name: "ROLQconst", argLength: 1, reg: gp11, asm: "ROLQ", aux: "Int64", resultInArg0: true}, // arg0 rotate left auxint, rotate amount 0-63
{name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int32", resultInArg0: true}, // arg0 rotate left auxint, rotate amount 0-31
{name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int16", resultInArg0: true}, // arg0 rotate left auxint, rotate amount 0-15
{name: "ROLBconst", argLength: 1, reg: gp11, asm: "ROLB", aux: "Int8", resultInArg0: true}, // arg0 rotate left auxint, rotate amount 0-7
// unary ops
{name: "NEGQ", argLength: 1, reg: gp11, asm: "NEGQ"}, // -arg0
{name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL"}, // -arg0
{name: "NEGW", argLength: 1, reg: gp11, asm: "NEGL"}, // -arg0
{name: "NEGB", argLength: 1, reg: gp11, asm: "NEGL"}, // -arg0
{name: "NEGQ", argLength: 1, reg: gp11, asm: "NEGQ", resultInArg0: true}, // -arg0
{name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true}, // -arg0
{name: "NEGW", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true}, // -arg0
{name: "NEGB", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true}, // -arg0
{name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ"}, // ^arg0
{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL"}, // ^arg0
{name: "NOTW", argLength: 1, reg: gp11, asm: "NOTL"}, // ^arg0
{name: "NOTB", argLength: 1, reg: gp11, asm: "NOTL"}, // ^arg0
{name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ", resultInArg0: true}, // ^arg0
{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
{name: "NOTW", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
{name: "NOTB", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
......@@ -360,7 +360,7 @@ func init() {
{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS"}, // convert float64 to float32
{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"}, // convert float32 to float64
{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR"}, // exclusive or, applied to X regs for float negation.
{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR", commutative: true, resultInArg0: true}, // exclusive or, applied to X regs for float negation.
{name: "LEAQ", argLength: 1, reg: gp11sb, aux: "SymOff", rematerializeable: true}, // arg0 + auxint + offset encoded in aux
{name: "LEAQ1", argLength: 2, reg: gp21sb, aux: "SymOff"}, // arg0 + arg1 + auxint + aux
......
......@@ -34,6 +34,7 @@ type opData struct {
rematerializeable bool
argLength int32 // number of arguments, if -1, then this operation has a variable number of arguments
commutative bool // this operation is commutative (e.g. addition)
resultInArg0 bool // prefer v and v.Args[0] to be allocated to the same register
}
type blockData struct {
......@@ -141,6 +142,9 @@ func genOp() {
if v.commutative {
fmt.Fprintln(w, "commutative: true,")
}
if v.resultInArg0 {
fmt.Fprintln(w, "resultInArg0: true,")
}
if a.name == "generic" {
fmt.Fprintln(w, "generic:true,")
fmt.Fprintln(w, "},") // close op
......
......@@ -26,6 +26,7 @@ type opInfo struct {
generic bool // this is a generic (arch-independent) opcode
rematerializeable bool // this op is rematerializeable
commutative bool // this operation is commutative (e.g. addition)
resultInArg0 bool // prefer v and v.Args[0] to be allocated to the same register
}
type inputInfo struct {
......
......@@ -593,6 +593,8 @@ var opcodeTable = [...]opInfo{
{
name: "ADDSS",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AADDSS,
reg: regInfo{
inputs: []inputInfo{
......@@ -607,6 +609,8 @@ var opcodeTable = [...]opInfo{
{
name: "ADDSD",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AADDSD,
reg: regInfo{
inputs: []inputInfo{
......@@ -621,6 +625,7 @@ var opcodeTable = [...]opInfo{
{
name: "SUBSS",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBSS,
reg: regInfo{
inputs: []inputInfo{
......@@ -636,6 +641,7 @@ var opcodeTable = [...]opInfo{
{
name: "SUBSD",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBSD,
reg: regInfo{
inputs: []inputInfo{
......@@ -651,6 +657,8 @@ var opcodeTable = [...]opInfo{
{
name: "MULSS",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AMULSS,
reg: regInfo{
inputs: []inputInfo{
......@@ -665,6 +673,8 @@ var opcodeTable = [...]opInfo{
{
name: "MULSD",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AMULSD,
reg: regInfo{
inputs: []inputInfo{
......@@ -679,6 +689,7 @@ var opcodeTable = [...]opInfo{
{
name: "DIVSS",
argLen: 2,
resultInArg0: true,
asm: x86.ADIVSS,
reg: regInfo{
inputs: []inputInfo{
......@@ -694,6 +705,7 @@ var opcodeTable = [...]opInfo{
{
name: "DIVSD",
argLen: 2,
resultInArg0: true,
asm: x86.ADIVSD,
reg: regInfo{
inputs: []inputInfo{
......@@ -841,6 +853,8 @@ var opcodeTable = [...]opInfo{
{
name: "ADDQ",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AADDQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -856,6 +870,8 @@ var opcodeTable = [...]opInfo{
{
name: "ADDL",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -871,6 +887,8 @@ var opcodeTable = [...]opInfo{
{
name: "ADDW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -886,6 +904,8 @@ var opcodeTable = [...]opInfo{
{
name: "ADDB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -902,6 +922,7 @@ var opcodeTable = [...]opInfo{
name: "ADDQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.AADDQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -917,6 +938,7 @@ var opcodeTable = [...]opInfo{
name: "ADDLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -932,6 +954,7 @@ var opcodeTable = [...]opInfo{
name: "ADDWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -947,6 +970,7 @@ var opcodeTable = [...]opInfo{
name: "ADDBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -961,6 +985,7 @@ var opcodeTable = [...]opInfo{
{
name: "SUBQ",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -976,6 +1001,7 @@ var opcodeTable = [...]opInfo{
{
name: "SUBL",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
......@@ -991,6 +1017,7 @@ var opcodeTable = [...]opInfo{
{
name: "SUBW",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1006,6 +1033,7 @@ var opcodeTable = [...]opInfo{
{
name: "SUBB",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1022,6 +1050,7 @@ var opcodeTable = [...]opInfo{
name: "SUBQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.ASUBQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1037,6 +1066,7 @@ var opcodeTable = [...]opInfo{
name: "SUBLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1052,6 +1082,7 @@ var opcodeTable = [...]opInfo{
name: "SUBWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1067,6 +1098,7 @@ var opcodeTable = [...]opInfo{
name: "SUBBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1081,6 +1113,8 @@ var opcodeTable = [...]opInfo{
{
name: "MULQ",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AIMULQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1096,6 +1130,8 @@ var opcodeTable = [...]opInfo{
{
name: "MULL",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AIMULL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1111,6 +1147,8 @@ var opcodeTable = [...]opInfo{
{
name: "MULW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
......@@ -1126,6 +1164,8 @@ var opcodeTable = [...]opInfo{
{
name: "MULB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
......@@ -1142,6 +1182,7 @@ var opcodeTable = [...]opInfo{
name: "MULQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.AIMULQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1157,6 +1198,7 @@ var opcodeTable = [...]opInfo{
name: "MULLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.AIMULL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1172,6 +1214,7 @@ var opcodeTable = [...]opInfo{
name: "MULWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
......@@ -1187,6 +1230,7 @@ var opcodeTable = [...]opInfo{
name: "MULBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
......@@ -1321,6 +1365,8 @@ var opcodeTable = [...]opInfo{
{
name: "AVGQU",
argLen: 2,
commutative: true,
resultInArg0: true,
reg: regInfo{
inputs: []inputInfo{
{0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
......@@ -1515,6 +1561,8 @@ var opcodeTable = [...]opInfo{
{
name: "ANDQ",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AANDQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1530,6 +1578,8 @@ var opcodeTable = [...]opInfo{
{
name: "ANDL",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1545,6 +1595,8 @@ var opcodeTable = [...]opInfo{
{
name: "ANDW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1560,6 +1612,8 @@ var opcodeTable = [...]opInfo{
{
name: "ANDB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1576,6 +1630,7 @@ var opcodeTable = [...]opInfo{
name: "ANDQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.AANDQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1591,6 +1646,7 @@ var opcodeTable = [...]opInfo{
name: "ANDLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1606,6 +1662,7 @@ var opcodeTable = [...]opInfo{
name: "ANDWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1621,6 +1678,7 @@ var opcodeTable = [...]opInfo{
name: "ANDBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1635,6 +1693,8 @@ var opcodeTable = [...]opInfo{
{
name: "ORQ",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AORQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1650,6 +1710,8 @@ var opcodeTable = [...]opInfo{
{
name: "ORL",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1665,6 +1727,8 @@ var opcodeTable = [...]opInfo{
{
name: "ORW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1680,6 +1744,8 @@ var opcodeTable = [...]opInfo{
{
name: "ORB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1696,6 +1762,7 @@ var opcodeTable = [...]opInfo{
name: "ORQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.AORQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1711,6 +1778,7 @@ var opcodeTable = [...]opInfo{
name: "ORLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1726,6 +1794,7 @@ var opcodeTable = [...]opInfo{
name: "ORWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1741,6 +1810,7 @@ var opcodeTable = [...]opInfo{
name: "ORBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1755,6 +1825,8 @@ var opcodeTable = [...]opInfo{
{
name: "XORQ",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AXORQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1770,6 +1842,8 @@ var opcodeTable = [...]opInfo{
{
name: "XORL",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1785,6 +1859,8 @@ var opcodeTable = [...]opInfo{
{
name: "XORW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1800,6 +1876,8 @@ var opcodeTable = [...]opInfo{
{
name: "XORB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1816,6 +1894,7 @@ var opcodeTable = [...]opInfo{
name: "XORQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.AXORQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -1831,6 +1910,7 @@ var opcodeTable = [...]opInfo{
name: "XORLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1846,6 +1926,7 @@ var opcodeTable = [...]opInfo{
name: "XORWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -1861,6 +1942,7 @@ var opcodeTable = [...]opInfo{
name: "XORBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2127,6 +2209,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHLQ",
argLen: 2,
resultInArg0: true,
asm: x86.ASHLQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2142,6 +2225,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHLL",
argLen: 2,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2157,6 +2241,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHLW",
argLen: 2,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2172,6 +2257,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHLB",
argLen: 2,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2188,6 +2274,7 @@ var opcodeTable = [...]opInfo{
name: "SHLQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.ASHLQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2203,6 +2290,7 @@ var opcodeTable = [...]opInfo{
name: "SHLLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2218,6 +2306,7 @@ var opcodeTable = [...]opInfo{
name: "SHLWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2233,6 +2322,7 @@ var opcodeTable = [...]opInfo{
name: "SHLBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2247,6 +2337,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHRQ",
argLen: 2,
resultInArg0: true,
asm: x86.ASHRQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2262,6 +2353,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHRL",
argLen: 2,
resultInArg0: true,
asm: x86.ASHRL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2277,6 +2369,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHRW",
argLen: 2,
resultInArg0: true,
asm: x86.ASHRW,
reg: regInfo{
inputs: []inputInfo{
......@@ -2292,6 +2385,7 @@ var opcodeTable = [...]opInfo{
{
name: "SHRB",
argLen: 2,
resultInArg0: true,
asm: x86.ASHRB,
reg: regInfo{
inputs: []inputInfo{
......@@ -2308,6 +2402,7 @@ var opcodeTable = [...]opInfo{
name: "SHRQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.ASHRQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2323,6 +2418,7 @@ var opcodeTable = [...]opInfo{
name: "SHRLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.ASHRL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2338,6 +2434,7 @@ var opcodeTable = [...]opInfo{
name: "SHRWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.ASHRW,
reg: regInfo{
inputs: []inputInfo{
......@@ -2353,6 +2450,7 @@ var opcodeTable = [...]opInfo{
name: "SHRBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.ASHRB,
reg: regInfo{
inputs: []inputInfo{
......@@ -2367,6 +2465,7 @@ var opcodeTable = [...]opInfo{
{
name: "SARQ",
argLen: 2,
resultInArg0: true,
asm: x86.ASARQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2382,6 +2481,7 @@ var opcodeTable = [...]opInfo{
{
name: "SARL",
argLen: 2,
resultInArg0: true,
asm: x86.ASARL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2397,6 +2497,7 @@ var opcodeTable = [...]opInfo{
{
name: "SARW",
argLen: 2,
resultInArg0: true,
asm: x86.ASARW,
reg: regInfo{
inputs: []inputInfo{
......@@ -2412,6 +2513,7 @@ var opcodeTable = [...]opInfo{
{
name: "SARB",
argLen: 2,
resultInArg0: true,
asm: x86.ASARB,
reg: regInfo{
inputs: []inputInfo{
......@@ -2428,6 +2530,7 @@ var opcodeTable = [...]opInfo{
name: "SARQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.ASARQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2443,6 +2546,7 @@ var opcodeTable = [...]opInfo{
name: "SARLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.ASARL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2458,6 +2562,7 @@ var opcodeTable = [...]opInfo{
name: "SARWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.ASARW,
reg: regInfo{
inputs: []inputInfo{
......@@ -2473,6 +2578,7 @@ var opcodeTable = [...]opInfo{
name: "SARBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.ASARB,
reg: regInfo{
inputs: []inputInfo{
......@@ -2488,6 +2594,7 @@ var opcodeTable = [...]opInfo{
name: "ROLQconst",
auxType: auxInt64,
argLen: 1,
resultInArg0: true,
asm: x86.AROLQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2503,6 +2610,7 @@ var opcodeTable = [...]opInfo{
name: "ROLLconst",
auxType: auxInt32,
argLen: 1,
resultInArg0: true,
asm: x86.AROLL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2518,6 +2626,7 @@ var opcodeTable = [...]opInfo{
name: "ROLWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AROLW,
reg: regInfo{
inputs: []inputInfo{
......@@ -2533,6 +2642,7 @@ var opcodeTable = [...]opInfo{
name: "ROLBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AROLB,
reg: regInfo{
inputs: []inputInfo{
......@@ -2547,6 +2657,7 @@ var opcodeTable = [...]opInfo{
{
name: "NEGQ",
argLen: 1,
resultInArg0: true,
asm: x86.ANEGQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2561,6 +2672,7 @@ var opcodeTable = [...]opInfo{
{
name: "NEGL",
argLen: 1,
resultInArg0: true,
asm: x86.ANEGL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2575,6 +2687,7 @@ var opcodeTable = [...]opInfo{
{
name: "NEGW",
argLen: 1,
resultInArg0: true,
asm: x86.ANEGL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2589,6 +2702,7 @@ var opcodeTable = [...]opInfo{
{
name: "NEGB",
argLen: 1,
resultInArg0: true,
asm: x86.ANEGL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2603,6 +2717,7 @@ var opcodeTable = [...]opInfo{
{
name: "NOTQ",
argLen: 1,
resultInArg0: true,
asm: x86.ANOTQ,
reg: regInfo{
inputs: []inputInfo{
......@@ -2617,6 +2732,7 @@ var opcodeTable = [...]opInfo{
{
name: "NOTL",
argLen: 1,
resultInArg0: true,
asm: x86.ANOTL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2631,6 +2747,7 @@ var opcodeTable = [...]opInfo{
{
name: "NOTW",
argLen: 1,
resultInArg0: true,
asm: x86.ANOTL,
reg: regInfo{
inputs: []inputInfo{
......@@ -2645,6 +2762,7 @@ var opcodeTable = [...]opInfo{
{
name: "NOTB",
argLen: 1,
resultInArg0: true,
asm: x86.ANOTL,
reg: regInfo{
inputs: []inputInfo{
......@@ -3164,6 +3282,8 @@ var opcodeTable = [...]opInfo{
{
name: "PXOR",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.APXOR,
reg: regInfo{
inputs: []inputInfo{
......
......@@ -923,14 +923,26 @@ func (s *regAllocState) regalloc(f *Func) {
s.freeRegs(regspec.clobbers)
// Pick register for output.
var mask regMask
if s.values[v.ID].needReg {
mask = regspec.outputs[0] &^ s.reserved()
mask := regspec.outputs[0] &^ s.reserved()
if mask>>33&1 != 0 {
s.f.Fatalf("bad mask %s\n", v.LongString())
}
if opcodeTable[v.Op].resultInArg0 {
r := register(s.f.getHome(args[0].ID).(*Register).Num)
if (mask&^s.used)>>r&1 != 0 {
mask = regMask(1) << r
}
if opcodeTable[v.Op].commutative {
r := register(s.f.getHome(args[1].ID).(*Register).Num)
if (mask&^s.used)>>r&1 != 0 {
mask = regMask(1) << r
}
}
// TODO: enforce resultInArg0 always, instead of treating it
// as a hint. Then we don't need the special cases adding
// moves all throughout ssa.go:genValue.
}
if mask != 0 {
r := s.allocReg(v, mask)
s.assignReg(r, v, v)
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment