1
0
mirror of https://github.com/golang/go synced 2024-10-04 17:21:20 -06:00

[dev.ssa] cmd/compile: handle boolean values for SSA on ARM

Fix hardcoded flag register mask in ssa/flagalloc.go by auto-generating
the mask.

Also fix a mistake (in previous CL) about conditional branches.

Progress on SSA backend for ARM. Still not complete. Now "container/ring"
package compiles and tests passed.

Updates #15365.

Change-Id: Id7c8805c30dbb8107baedb485ed0f71f59ed6ea8
Reviewed-on: https://go-review.googlesource.com/23093
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Cherry Zhang 2016-05-13 11:25:07 -04:00
parent e2848de9ef
commit ccaed50c7b
11 changed files with 616 additions and 49 deletions

View File

@ -193,7 +193,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpARMMOVBreg, case ssa.OpARMMOVBreg,
ssa.OpARMMOVBUreg, ssa.OpARMMOVBUreg,
ssa.OpARMMOVHreg, ssa.OpARMMOVHreg,
ssa.OpARMMOVHUreg: ssa.OpARMMOVHUreg,
ssa.OpARMMVN:
if v.Type.IsMemory() { if v.Type.IsMemory() {
v.Fatalf("memory operand for %s", v.LongString()) v.Fatalf("memory operand for %s", v.LongString())
} }
@ -270,12 +271,37 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
ssa.OpARMLessEqualU, ssa.OpARMLessEqualU,
ssa.OpARMGreaterThanU, ssa.OpARMGreaterThanU,
ssa.OpARMGreaterEqualU: ssa.OpARMGreaterEqualU:
v.Fatalf("pseudo-op made it to output: %s", v.LongString()) // generate boolean values
// use conditional move
p := gc.Prog(arm.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 0
p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v)
p = gc.Prog(arm.AMOVW)
p.Scond = condBits[v.Op]
p.From.Type = obj.TYPE_CONST
p.From.Offset = 1
p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v)
default: default:
v.Unimplementedf("genValue not implemented: %s", v.LongString()) v.Unimplementedf("genValue not implemented: %s", v.LongString())
} }
} }
var condBits = map[ssa.Op]uint8{
ssa.OpARMEqual: arm.C_SCOND_EQ,
ssa.OpARMNotEqual: arm.C_SCOND_NE,
ssa.OpARMLessThan: arm.C_SCOND_LT,
ssa.OpARMLessThanU: arm.C_SCOND_LO,
ssa.OpARMLessEqual: arm.C_SCOND_LE,
ssa.OpARMLessEqualU: arm.C_SCOND_LS,
ssa.OpARMGreaterThan: arm.C_SCOND_GT,
ssa.OpARMGreaterThanU: arm.C_SCOND_HI,
ssa.OpARMGreaterEqual: arm.C_SCOND_GE,
ssa.OpARMGreaterEqualU: arm.C_SCOND_HS,
}
var blockJump = map[ssa.BlockKind]struct { var blockJump = map[ssa.BlockKind]struct {
asm, invasm obj.As asm, invasm obj.As
}{ }{
@ -285,8 +311,8 @@ var blockJump = map[ssa.BlockKind]struct {
ssa.BlockARMGE: {arm.ABGE, arm.ABLT}, ssa.BlockARMGE: {arm.ABGE, arm.ABLT},
ssa.BlockARMLE: {arm.ABLE, arm.ABGT}, ssa.BlockARMLE: {arm.ABLE, arm.ABGT},
ssa.BlockARMGT: {arm.ABGT, arm.ABLE}, ssa.BlockARMGT: {arm.ABGT, arm.ABLE},
ssa.BlockARMULT: {arm.ABCS, arm.ABCC}, ssa.BlockARMULT: {arm.ABLO, arm.ABHS},
ssa.BlockARMUGE: {arm.ABCC, arm.ABCS}, ssa.BlockARMUGE: {arm.ABHS, arm.ABLO},
ssa.BlockARMUGT: {arm.ABHI, arm.ABLS}, ssa.BlockARMUGT: {arm.ABHI, arm.ABLS},
ssa.BlockARMULE: {arm.ABLS, arm.ABHI}, ssa.BlockARMULE: {arm.ABLS, arm.ABHI},
} }

View File

@ -1135,6 +1135,7 @@ var opToSSA = map[opAndType]ssa.Op{
opAndType{OEQ, TFUNC}: ssa.OpEqPtr, opAndType{OEQ, TFUNC}: ssa.OpEqPtr,
opAndType{OEQ, TMAP}: ssa.OpEqPtr, opAndType{OEQ, TMAP}: ssa.OpEqPtr,
opAndType{OEQ, TCHAN}: ssa.OpEqPtr, opAndType{OEQ, TCHAN}: ssa.OpEqPtr,
opAndType{OEQ, TPTR32}: ssa.OpEqPtr,
opAndType{OEQ, TPTR64}: ssa.OpEqPtr, opAndType{OEQ, TPTR64}: ssa.OpEqPtr,
opAndType{OEQ, TUINTPTR}: ssa.OpEqPtr, opAndType{OEQ, TUINTPTR}: ssa.OpEqPtr,
opAndType{OEQ, TUNSAFEPTR}: ssa.OpEqPtr, opAndType{OEQ, TUNSAFEPTR}: ssa.OpEqPtr,
@ -1155,6 +1156,7 @@ var opToSSA = map[opAndType]ssa.Op{
opAndType{ONE, TFUNC}: ssa.OpNeqPtr, opAndType{ONE, TFUNC}: ssa.OpNeqPtr,
opAndType{ONE, TMAP}: ssa.OpNeqPtr, opAndType{ONE, TMAP}: ssa.OpNeqPtr,
opAndType{ONE, TCHAN}: ssa.OpNeqPtr, opAndType{ONE, TCHAN}: ssa.OpNeqPtr,
opAndType{ONE, TPTR32}: ssa.OpNeqPtr,
opAndType{ONE, TPTR64}: ssa.OpNeqPtr, opAndType{ONE, TPTR64}: ssa.OpNeqPtr,
opAndType{ONE, TUINTPTR}: ssa.OpNeqPtr, opAndType{ONE, TUINTPTR}: ssa.OpNeqPtr,
opAndType{ONE, TUNSAFEPTR}: ssa.OpNeqPtr, opAndType{ONE, TUNSAFEPTR}: ssa.OpNeqPtr,

View File

@ -19,6 +19,7 @@ type Config struct {
lowerBlock func(*Block) bool // lowering function lowerBlock func(*Block) bool // lowering function
lowerValue func(*Value, *Config) bool // lowering function lowerValue func(*Value, *Config) bool // lowering function
registers []Register // machine registers registers []Register // machine registers
flagRegMask regMask // flag register mask
fe Frontend // callbacks into compiler frontend fe Frontend // callbacks into compiler frontend
HTML *HTMLWriter // html writer, for debugging HTML *HTMLWriter // html writer, for debugging
ctxt *obj.Link // Generic arch information ctxt *obj.Link // Generic arch information
@ -126,6 +127,7 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config
c.lowerBlock = rewriteBlockAMD64 c.lowerBlock = rewriteBlockAMD64
c.lowerValue = rewriteValueAMD64 c.lowerValue = rewriteValueAMD64
c.registers = registersAMD64[:] c.registers = registersAMD64[:]
c.flagRegMask = flagRegMaskAMD64
case "386": case "386":
c.IntSize = 4 c.IntSize = 4
c.PtrSize = 4 c.PtrSize = 4
@ -137,6 +139,7 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config
c.lowerBlock = rewriteBlockARM c.lowerBlock = rewriteBlockARM
c.lowerValue = rewriteValueARM c.lowerValue = rewriteValueARM
c.registers = registersARM[:] c.registers = registersARM[:]
c.flagRegMask = flagRegMaskARM
default: default:
fe.Unimplementedf(0, "arch %s not implemented", arch) fe.Unimplementedf(0, "arch %s not implemented", arch)
} }

View File

@ -4,8 +4,6 @@
package ssa package ssa
const flagRegMask = regMask(1) << 33 // TODO: arch-specific
// flagalloc allocates the flag register among all the flag-generating // flagalloc allocates the flag register among all the flag-generating
// instructions. Flag values are recomputed if they need to be // instructions. Flag values are recomputed if they need to be
// spilled/restored. // spilled/restored.
@ -33,7 +31,7 @@ func flagalloc(f *Func) {
if v == flag { if v == flag {
flag = nil flag = nil
} }
if opcodeTable[v.Op].reg.clobbers&flagRegMask != 0 { if opcodeTable[v.Op].reg.clobbers&f.Config.flagRegMask != 0 {
flag = nil flag = nil
} }
for _, a := range v.Args { for _, a := range v.Args {
@ -105,7 +103,7 @@ func flagalloc(f *Func) {
} }
// Issue v. // Issue v.
b.Values = append(b.Values, v) b.Values = append(b.Values, v)
if opcodeTable[v.Op].reg.clobbers&flagRegMask != 0 { if opcodeTable[v.Op].reg.clobbers&f.Config.flagRegMask != 0 {
flag = nil flag = nil
} }
if v.Type.IsFlags() { if v.Type.IsFlags() {

View File

@ -551,5 +551,6 @@ func init() {
ops: AMD64ops, ops: AMD64ops,
blocks: AMD64blocks, blocks: AMD64blocks,
regnames: regNamesAMD64, regnames: regNamesAMD64,
flagmask: flags,
}) })
} }

View File

@ -2,11 +2,43 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
(AddPtr x y) -> (ADD x y)
(Add32 x y) -> (ADD x y) (Add32 x y) -> (ADD x y)
(Add16 x y) -> (ADD x y)
(Add8 x y) -> (ADD x y)
(SubPtr x y) -> (SUB x y)
(Sub32 x y) -> (SUB x y) (Sub32 x y) -> (SUB x y)
(Sub16 x y) -> (SUB x y)
(Sub8 x y) -> (SUB x y)
(And32 x y) -> (AND x y) (And32 x y) -> (AND x y)
(Or32 x y) -> (OR x y) (And16 x y) -> (AND x y)
(And8 x y) -> (AND x y)
(Or32 x y) -> (OR x y)
(Or16 x y) -> (OR x y)
(Or8 x y) -> (OR x y)
(Xor32 x y) -> (XOR x y) (Xor32 x y) -> (XOR x y)
(Xor16 x y) -> (XOR x y)
(Xor8 x y) -> (XOR x y)
// unary ops
(Neg32 x) -> (RSBconst [0] x)
(Neg16 x) -> (RSBconst [0] x)
(Neg8 x) -> (RSBconst [0] x)
(Com32 x) -> (MVN x)
(Com16 x) -> (MVN x)
(Com8 x) -> (MVN x)
// boolean ops -- booleans are represented with 0=false, 1=true
(AndB x y) -> (AND x y)
(OrB x y) -> (OR x y)
(EqB x y) -> (XORconst [1] (XOR <config.fe.TypeBool()> x y))
(NeqB x y) -> (XOR x y)
(Not x) -> (XORconst [1] x)
(Const8 [val]) -> (MOVWconst [val]) (Const8 [val]) -> (MOVWconst [val])
(Const16 [val]) -> (MOVWconst [val]) (Const16 [val]) -> (MOVWconst [val])
@ -29,10 +61,12 @@
(Eq8 x y) -> (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) (Eq8 x y) -> (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
(Eq16 x y) -> (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) (Eq16 x y) -> (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
(Eq32 x y) -> (Equal (CMP x y)) (Eq32 x y) -> (Equal (CMP x y))
(EqPtr x y) -> (Equal (CMP x y))
(Neq8 x y) -> (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) (Neq8 x y) -> (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
(Neq16 x y) -> (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) (Neq16 x y) -> (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
(Neq32 x y) -> (NotEqual (CMP x y)) (Neq32 x y) -> (NotEqual (CMP x y))
(NeqPtr x y) -> (NotEqual (CMP x y))
(Less8 x y) -> (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y))) (Less8 x y) -> (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
(Less16 x y) -> (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y))) (Less16 x y) -> (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
@ -89,6 +123,9 @@
// checks // checks
(NilCheck ptr mem) -> (LoweredNilCheck ptr mem) (NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
(IsNonNil ptr) -> (NotEqual (CMPconst [0] ptr))
(IsInBounds idx len) -> (LessThanU (CMP idx len))
(IsSliceInBounds idx len) -> (LessEqualU (CMP idx len))
// Absorb pseudo-ops into blocks. // Absorb pseudo-ops into blocks.
(If (Equal cc) yes no) -> (EQ cc yes no) (If (Equal cc) yes no) -> (EQ cc yes no)

View File

@ -80,12 +80,12 @@ func init() {
gp01 = regInfo{inputs: []regMask{}, outputs: []regMask{gp}} gp01 = regInfo{inputs: []regMask{}, outputs: []regMask{gp}}
gp11 = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}} gp11 = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}
gp11sb = regInfo{inputs: []regMask{gpspsb}, outputs: []regMask{gp}} gp11sb = regInfo{inputs: []regMask{gpspsb}, outputs: []regMask{gp}}
gp11flags = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp | flags}} gp1flags = regInfo{inputs: []regMask{gp}, outputs: []regMask{flags}}
gp21 = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}} gp21 = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
gp2flags = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp | flags}} gp2flags = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{flags}}
gpload = regInfo{inputs: []regMask{gpspsb}, outputs: []regMask{gp}} gpload = regInfo{inputs: []regMask{gpspsb}, outputs: []regMask{gp}}
gpstore = regInfo{inputs: []regMask{gpspsb, gp}, outputs: []regMask{}} gpstore = regInfo{inputs: []regMask{gpspsb, gp}, outputs: []regMask{}}
flagsgp = regInfo{inputs: []regMask{gp | flags}, outputs: []regMask{gp}} readflags = regInfo{inputs: []regMask{flags}, outputs: []regMask{gp}}
) )
ops := []opData{ ops := []opData{
// binary ops // binary ops
@ -105,14 +105,17 @@ func init() {
{name: "BIC", argLength: 2, reg: gp21, asm: "BIC"}, // arg0 &^ arg1 {name: "BIC", argLength: 2, reg: gp21, asm: "BIC"}, // arg0 &^ arg1
{name: "BICconst", argLength: 1, reg: gp11, asm: "BIC", aux: "Int32"}, // arg0 &^ auxInt {name: "BICconst", argLength: 1, reg: gp11, asm: "BIC", aux: "Int32"}, // arg0 &^ auxInt
{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1 // unary ops
{name: "CMPconst", argLength: 1, reg: gp11flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt {name: "MVN", argLength: 1, reg: gp11, asm: "MVN"}, // ^arg0
{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags"}, // arg0 compare to -arg1
{name: "CMNconst", argLength: 1, reg: gp11flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt {name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1
{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0 {name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt
{name: "TSTconst", argLength: 1, reg: gp11flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0 {name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags"}, // arg0 compare to -arg1
{name: "TEQ", argLength: 2, reg: gp2flags, asm: "TEQ", typ: "Flags", commutative: true}, // arg0 ^ arg1 compare to 0 {name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt
{name: "TEQconst", argLength: 1, reg: gp11flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ auxInt compare to 0 {name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0
{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0
{name: "TEQ", argLength: 2, reg: gp2flags, asm: "TEQ", typ: "Flags", commutative: true}, // arg0 ^ arg1 compare to 0
{name: "TEQconst", argLength: 1, reg: gp1flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ auxInt compare to 0
{name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", rematerializeable: true}, // 32 low bits of auxint {name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", rematerializeable: true}, // 32 low bits of auxint
@ -140,16 +143,16 @@ func init() {
// pseudo-ops // pseudo-ops
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}, clobbers: flags}}, // panic if arg0 is nil. arg1=mem. {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}, clobbers: flags}}, // panic if arg0 is nil. arg1=mem.
{name: "Equal", argLength: 1, reg: flagsgp}, // bool, true flags encode x==y false otherwise. {name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise.
{name: "NotEqual", argLength: 1, reg: flagsgp}, // bool, true flags encode x!=y false otherwise. {name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise.
{name: "LessThan", argLength: 1, reg: flagsgp}, // bool, true flags encode signed x<y false otherwise. {name: "LessThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x<y false otherwise.
{name: "LessEqual", argLength: 1, reg: flagsgp}, // bool, true flags encode signed x<=y false otherwise. {name: "LessEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x<=y false otherwise.
{name: "GreaterThan", argLength: 1, reg: flagsgp}, // bool, true flags encode signed x>y false otherwise. {name: "GreaterThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x>y false otherwise.
{name: "GreaterEqual", argLength: 1, reg: flagsgp}, // bool, true flags encode signed x>=y false otherwise. {name: "GreaterEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x>=y false otherwise.
{name: "LessThanU", argLength: 1, reg: flagsgp}, // bool, true flags encode unsigned x<y false otherwise. {name: "LessThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<y false otherwise.
{name: "LessEqualU", argLength: 1, reg: flagsgp}, // bool, true flags encode unsigned x<=y false otherwise. {name: "LessEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<=y false otherwise.
{name: "GreaterThanU", argLength: 1, reg: flagsgp}, // bool, true flags encode unsigned x>y false otherwise. {name: "GreaterThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>y false otherwise.
{name: "GreaterEqualU", argLength: 1, reg: flagsgp}, // bool, true flags encode unsigned x>=y false otherwise. {name: "GreaterEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>=y false otherwise.
} }
blocks := []blockData{ blocks := []blockData{
@ -172,5 +175,6 @@ func init() {
ops: ops, ops: ops,
blocks: blocks, blocks: blocks,
regnames: regNamesARM, regnames: regNamesARM,
flagmask: flags,
}) })
} }

View File

@ -27,6 +27,7 @@ type arch struct {
ops []opData ops []opData
blocks []blockData blocks []blockData
regnames []string regnames []string
flagmask regMask
generic bool generic bool
} }
@ -223,6 +224,7 @@ func genOp() {
fmt.Fprintf(w, " {%d, \"%s\"},\n", i, r) fmt.Fprintf(w, " {%d, \"%s\"},\n", i, r)
} }
fmt.Fprintln(w, "}") fmt.Fprintln(w, "}")
fmt.Fprintf(w, "var flagRegMask%s = regMask(%d)\n", a.name, a.flagmask)
} }
// gofmt result // gofmt result

View File

@ -337,6 +337,7 @@ const (
OpARMXORconst OpARMXORconst
OpARMBIC OpARMBIC
OpARMBICconst OpARMBICconst
OpARMMVN
OpARMCMP OpARMCMP
OpARMCMPconst OpARMCMPconst
OpARMCMN OpARMCMN
@ -4040,6 +4041,19 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "MVN",
argLen: 1,
asm: arm.AMVN,
reg: regInfo{
inputs: []inputInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
},
outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
},
},
},
{ {
name: "CMP", name: "CMP",
argLen: 2, argLen: 2,
@ -4050,7 +4064,7 @@ var opcodeTable = [...]opInfo{
{1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4064,7 +4078,7 @@ var opcodeTable = [...]opInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4078,7 +4092,7 @@ var opcodeTable = [...]opInfo{
{1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4092,7 +4106,7 @@ var opcodeTable = [...]opInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4107,7 +4121,7 @@ var opcodeTable = [...]opInfo{
{1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4121,7 +4135,7 @@ var opcodeTable = [...]opInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4136,7 +4150,7 @@ var opcodeTable = [...]opInfo{
{1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4150,7 +4164,7 @@ var opcodeTable = [...]opInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
}, },
outputs: []regMask{ outputs: []regMask{
70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS 65536, // FLAGS
}, },
}, },
}, },
@ -4386,7 +4400,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4398,7 +4412,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4410,7 +4424,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4422,7 +4436,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4434,7 +4448,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4446,7 +4460,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4458,7 +4472,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4470,7 +4484,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4482,7 +4496,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -4494,7 +4508,7 @@ var opcodeTable = [...]opInfo{
argLen: 1, argLen: 1,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 70655}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS {0, 65536}, // FLAGS
}, },
outputs: []regMask{ outputs: []regMask{
5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@ -6027,6 +6041,7 @@ var registersAMD64 = [...]Register{
{32, "SB"}, {32, "SB"},
{33, "FLAGS"}, {33, "FLAGS"},
} }
var flagRegMaskAMD64 = regMask(8589934592)
var registersARM = [...]Register{ var registersARM = [...]Register{
{0, "R0"}, {0, "R0"},
{1, "R1"}, {1, "R1"},
@ -6047,3 +6062,4 @@ var registersARM = [...]Register{
{16, "FLAGS"}, {16, "FLAGS"},
{17, "SB"}, {17, "SB"},
} }
var flagRegMaskARM = regMask(65536)

View File

@ -985,7 +985,7 @@ func (s *regAllocState) regalloc(f *Func) {
args = append(args[:0], v.Args...) args = append(args[:0], v.Args...)
for _, i := range regspec.inputs { for _, i := range regspec.inputs {
mask := i.regs mask := i.regs
if mask == flagRegMask { if mask == f.Config.flagRegMask {
// TODO: remove flag input from regspec.inputs. // TODO: remove flag input from regspec.inputs.
continue continue
} }

View File

@ -10,14 +10,32 @@ func rewriteValueARM(v *Value, config *Config) bool {
switch v.Op { switch v.Op {
case OpARMADD: case OpARMADD:
return rewriteValueARM_OpARMADD(v, config) return rewriteValueARM_OpARMADD(v, config)
case OpAdd16:
return rewriteValueARM_OpAdd16(v, config)
case OpAdd32: case OpAdd32:
return rewriteValueARM_OpAdd32(v, config) return rewriteValueARM_OpAdd32(v, config)
case OpAdd8:
return rewriteValueARM_OpAdd8(v, config)
case OpAddPtr:
return rewriteValueARM_OpAddPtr(v, config)
case OpAddr: case OpAddr:
return rewriteValueARM_OpAddr(v, config) return rewriteValueARM_OpAddr(v, config)
case OpAnd16:
return rewriteValueARM_OpAnd16(v, config)
case OpAnd32: case OpAnd32:
return rewriteValueARM_OpAnd32(v, config) return rewriteValueARM_OpAnd32(v, config)
case OpAnd8:
return rewriteValueARM_OpAnd8(v, config)
case OpAndB:
return rewriteValueARM_OpAndB(v, config)
case OpClosureCall: case OpClosureCall:
return rewriteValueARM_OpClosureCall(v, config) return rewriteValueARM_OpClosureCall(v, config)
case OpCom16:
return rewriteValueARM_OpCom16(v, config)
case OpCom32:
return rewriteValueARM_OpCom32(v, config)
case OpCom8:
return rewriteValueARM_OpCom8(v, config)
case OpConst16: case OpConst16:
return rewriteValueARM_OpConst16(v, config) return rewriteValueARM_OpConst16(v, config)
case OpConst32: case OpConst32:
@ -36,6 +54,10 @@ func rewriteValueARM(v *Value, config *Config) bool {
return rewriteValueARM_OpEq32(v, config) return rewriteValueARM_OpEq32(v, config)
case OpEq8: case OpEq8:
return rewriteValueARM_OpEq8(v, config) return rewriteValueARM_OpEq8(v, config)
case OpEqB:
return rewriteValueARM_OpEqB(v, config)
case OpEqPtr:
return rewriteValueARM_OpEqPtr(v, config)
case OpGeq16: case OpGeq16:
return rewriteValueARM_OpGeq16(v, config) return rewriteValueARM_OpGeq16(v, config)
case OpGeq16U: case OpGeq16U:
@ -64,6 +86,12 @@ func rewriteValueARM(v *Value, config *Config) bool {
return rewriteValueARM_OpGreater8U(v, config) return rewriteValueARM_OpGreater8U(v, config)
case OpInterCall: case OpInterCall:
return rewriteValueARM_OpInterCall(v, config) return rewriteValueARM_OpInterCall(v, config)
case OpIsInBounds:
return rewriteValueARM_OpIsInBounds(v, config)
case OpIsNonNil:
return rewriteValueARM_OpIsNonNil(v, config)
case OpIsSliceInBounds:
return rewriteValueARM_OpIsSliceInBounds(v, config)
case OpLeq16: case OpLeq16:
return rewriteValueARM_OpLeq16(v, config) return rewriteValueARM_OpLeq16(v, config)
case OpLeq16U: case OpLeq16U:
@ -106,18 +134,36 @@ func rewriteValueARM(v *Value, config *Config) bool {
return rewriteValueARM_OpARMMOVWload(v, config) return rewriteValueARM_OpARMMOVWload(v, config)
case OpARMMOVWstore: case OpARMMOVWstore:
return rewriteValueARM_OpARMMOVWstore(v, config) return rewriteValueARM_OpARMMOVWstore(v, config)
case OpNeg16:
return rewriteValueARM_OpNeg16(v, config)
case OpNeg32:
return rewriteValueARM_OpNeg32(v, config)
case OpNeg8:
return rewriteValueARM_OpNeg8(v, config)
case OpNeq16: case OpNeq16:
return rewriteValueARM_OpNeq16(v, config) return rewriteValueARM_OpNeq16(v, config)
case OpNeq32: case OpNeq32:
return rewriteValueARM_OpNeq32(v, config) return rewriteValueARM_OpNeq32(v, config)
case OpNeq8: case OpNeq8:
return rewriteValueARM_OpNeq8(v, config) return rewriteValueARM_OpNeq8(v, config)
case OpNeqB:
return rewriteValueARM_OpNeqB(v, config)
case OpNeqPtr:
return rewriteValueARM_OpNeqPtr(v, config)
case OpNilCheck: case OpNilCheck:
return rewriteValueARM_OpNilCheck(v, config) return rewriteValueARM_OpNilCheck(v, config)
case OpNot:
return rewriteValueARM_OpNot(v, config)
case OpOffPtr: case OpOffPtr:
return rewriteValueARM_OpOffPtr(v, config) return rewriteValueARM_OpOffPtr(v, config)
case OpOr16:
return rewriteValueARM_OpOr16(v, config)
case OpOr32: case OpOr32:
return rewriteValueARM_OpOr32(v, config) return rewriteValueARM_OpOr32(v, config)
case OpOr8:
return rewriteValueARM_OpOr8(v, config)
case OpOrB:
return rewriteValueARM_OpOrB(v, config)
case OpSignExt16to32: case OpSignExt16to32:
return rewriteValueARM_OpSignExt16to32(v, config) return rewriteValueARM_OpSignExt16to32(v, config)
case OpSignExt8to16: case OpSignExt8to16:
@ -128,16 +174,26 @@ func rewriteValueARM(v *Value, config *Config) bool {
return rewriteValueARM_OpStaticCall(v, config) return rewriteValueARM_OpStaticCall(v, config)
case OpStore: case OpStore:
return rewriteValueARM_OpStore(v, config) return rewriteValueARM_OpStore(v, config)
case OpSub16:
return rewriteValueARM_OpSub16(v, config)
case OpSub32: case OpSub32:
return rewriteValueARM_OpSub32(v, config) return rewriteValueARM_OpSub32(v, config)
case OpSub8:
return rewriteValueARM_OpSub8(v, config)
case OpSubPtr:
return rewriteValueARM_OpSubPtr(v, config)
case OpTrunc16to8: case OpTrunc16to8:
return rewriteValueARM_OpTrunc16to8(v, config) return rewriteValueARM_OpTrunc16to8(v, config)
case OpTrunc32to16: case OpTrunc32to16:
return rewriteValueARM_OpTrunc32to16(v, config) return rewriteValueARM_OpTrunc32to16(v, config)
case OpTrunc32to8: case OpTrunc32to8:
return rewriteValueARM_OpTrunc32to8(v, config) return rewriteValueARM_OpTrunc32to8(v, config)
case OpXor16:
return rewriteValueARM_OpXor16(v, config)
case OpXor32: case OpXor32:
return rewriteValueARM_OpXor32(v, config) return rewriteValueARM_OpXor32(v, config)
case OpXor8:
return rewriteValueARM_OpXor8(v, config)
case OpZeroExt16to32: case OpZeroExt16to32:
return rewriteValueARM_OpZeroExt16to32(v, config) return rewriteValueARM_OpZeroExt16to32(v, config)
case OpZeroExt8to16: case OpZeroExt8to16:
@ -182,6 +238,21 @@ func rewriteValueARM_OpARMADD(v *Value, config *Config) bool {
} }
return false return false
} }
func rewriteValueARM_OpAdd16(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Add16 x y)
// cond:
// result: (ADD x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMADD)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpAdd32(v *Value, config *Config) bool { func rewriteValueARM_OpAdd32(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -197,6 +268,36 @@ func rewriteValueARM_OpAdd32(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpAdd8(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Add8 x y)
// cond:
// result: (ADD x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMADD)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpAddPtr(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (AddPtr x y)
// cond:
// result: (ADD x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMADD)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpAddr(v *Value, config *Config) bool { func rewriteValueARM_OpAddr(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -212,6 +313,21 @@ func rewriteValueARM_OpAddr(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpAnd16(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (And16 x y)
// cond:
// result: (AND x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMAND)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpAnd32(v *Value, config *Config) bool { func rewriteValueARM_OpAnd32(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -227,6 +343,36 @@ func rewriteValueARM_OpAnd32(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpAnd8(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (And8 x y)
// cond:
// result: (AND x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMAND)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpAndB(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (AndB x y)
// cond:
// result: (AND x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMAND)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpClosureCall(v *Value, config *Config) bool { func rewriteValueARM_OpClosureCall(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -246,6 +392,45 @@ func rewriteValueARM_OpClosureCall(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpCom16(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Com16 x)
// cond:
// result: (MVN x)
for {
x := v.Args[0]
v.reset(OpARMMVN)
v.AddArg(x)
return true
}
}
func rewriteValueARM_OpCom32(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Com32 x)
// cond:
// result: (MVN x)
for {
x := v.Args[0]
v.reset(OpARMMVN)
v.AddArg(x)
return true
}
}
func rewriteValueARM_OpCom8(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Com8 x)
// cond:
// result: (MVN x)
for {
x := v.Args[0]
v.reset(OpARMMVN)
v.AddArg(x)
return true
}
}
func rewriteValueARM_OpConst16(v *Value, config *Config) bool { func rewriteValueARM_OpConst16(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -384,6 +569,41 @@ func rewriteValueARM_OpEq8(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpEqB(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (EqB x y)
// cond:
// result: (XORconst [1] (XOR <config.fe.TypeBool()> x y))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMXORconst)
v.AuxInt = 1
v0 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeBool())
v0.AddArg(x)
v0.AddArg(y)
v.AddArg(v0)
return true
}
}
func rewriteValueARM_OpEqPtr(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (EqPtr x y)
// cond:
// result: (Equal (CMP x y))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMEqual)
v0 := b.NewValue0(v.Line, OpARMCMP, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
v.AddArg(v0)
return true
}
}
func rewriteValueARM_OpGeq16(v *Value, config *Config) bool { func rewriteValueARM_OpGeq16(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -652,6 +872,56 @@ func rewriteValueARM_OpInterCall(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpIsInBounds(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (IsInBounds idx len)
// cond:
// result: (LessThanU (CMP idx len))
for {
idx := v.Args[0]
len := v.Args[1]
v.reset(OpARMLessThanU)
v0 := b.NewValue0(v.Line, OpARMCMP, TypeFlags)
v0.AddArg(idx)
v0.AddArg(len)
v.AddArg(v0)
return true
}
}
func rewriteValueARM_OpIsNonNil(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (IsNonNil ptr)
// cond:
// result: (NotEqual (CMPconst [0] ptr))
for {
ptr := v.Args[0]
v.reset(OpARMNotEqual)
v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags)
v0.AuxInt = 0
v0.AddArg(ptr)
v.AddArg(v0)
return true
}
}
func rewriteValueARM_OpIsSliceInBounds(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (IsSliceInBounds idx len)
// cond:
// result: (LessEqualU (CMP idx len))
for {
idx := v.Args[0]
len := v.Args[1]
v.reset(OpARMLessEqualU)
v0 := b.NewValue0(v.Line, OpARMCMP, TypeFlags)
v0.AddArg(idx)
v0.AddArg(len)
v.AddArg(v0)
return true
}
}
func rewriteValueARM_OpLeq16(v *Value, config *Config) bool { func rewriteValueARM_OpLeq16(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1221,6 +1491,48 @@ func rewriteValueARM_OpARMMOVWstore(v *Value, config *Config) bool {
} }
return false return false
} }
func rewriteValueARM_OpNeg16(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Neg16 x)
// cond:
// result: (RSBconst [0] x)
for {
x := v.Args[0]
v.reset(OpARMRSBconst)
v.AuxInt = 0
v.AddArg(x)
return true
}
}
func rewriteValueARM_OpNeg32(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Neg32 x)
// cond:
// result: (RSBconst [0] x)
for {
x := v.Args[0]
v.reset(OpARMRSBconst)
v.AuxInt = 0
v.AddArg(x)
return true
}
}
func rewriteValueARM_OpNeg8(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Neg8 x)
// cond:
// result: (RSBconst [0] x)
for {
x := v.Args[0]
v.reset(OpARMRSBconst)
v.AuxInt = 0
v.AddArg(x)
return true
}
}
func rewriteValueARM_OpNeq16(v *Value, config *Config) bool { func rewriteValueARM_OpNeq16(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1280,6 +1592,38 @@ func rewriteValueARM_OpNeq8(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpNeqB(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (NeqB x y)
// cond:
// result: (XOR x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMXOR)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpNeqPtr(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (NeqPtr x y)
// cond:
// result: (NotEqual (CMP x y))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMNotEqual)
v0 := b.NewValue0(v.Line, OpARMCMP, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
v.AddArg(v0)
return true
}
}
func rewriteValueARM_OpNilCheck(v *Value, config *Config) bool { func rewriteValueARM_OpNilCheck(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1295,6 +1639,20 @@ func rewriteValueARM_OpNilCheck(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpNot(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Not x)
// cond:
// result: (XORconst [1] x)
for {
x := v.Args[0]
v.reset(OpARMXORconst)
v.AuxInt = 1
v.AddArg(x)
return true
}
}
func rewriteValueARM_OpOffPtr(v *Value, config *Config) bool { func rewriteValueARM_OpOffPtr(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1312,6 +1670,21 @@ func rewriteValueARM_OpOffPtr(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpOr16(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Or16 x y)
// cond:
// result: (OR x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMOR)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpOr32(v *Value, config *Config) bool { func rewriteValueARM_OpOr32(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1327,6 +1700,36 @@ func rewriteValueARM_OpOr32(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpOr8(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Or8 x y)
// cond:
// result: (OR x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMOR)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpOrB(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (OrB x y)
// cond:
// result: (OR x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMOR)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpSignExt16to32(v *Value, config *Config) bool { func rewriteValueARM_OpSignExt16to32(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1436,6 +1839,21 @@ func rewriteValueARM_OpStore(v *Value, config *Config) bool {
} }
return false return false
} }
func rewriteValueARM_OpSub16(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Sub16 x y)
// cond:
// result: (SUB x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMSUB)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpSub32(v *Value, config *Config) bool { func rewriteValueARM_OpSub32(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1451,6 +1869,36 @@ func rewriteValueARM_OpSub32(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpSub8(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Sub8 x y)
// cond:
// result: (SUB x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMSUB)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpSubPtr(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (SubPtr x y)
// cond:
// result: (SUB x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMSUB)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpTrunc16to8(v *Value, config *Config) bool { func rewriteValueARM_OpTrunc16to8(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1493,6 +1941,21 @@ func rewriteValueARM_OpTrunc32to8(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpXor16(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Xor16 x y)
// cond:
// result: (XOR x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMXOR)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpXor32(v *Value, config *Config) bool { func rewriteValueARM_OpXor32(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
@ -1508,6 +1971,21 @@ func rewriteValueARM_OpXor32(v *Value, config *Config) bool {
return true return true
} }
} }
func rewriteValueARM_OpXor8(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (Xor8 x y)
// cond:
// result: (XOR x y)
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpARMXOR)
v.AddArg(x)
v.AddArg(y)
return true
}
}
func rewriteValueARM_OpZeroExt16to32(v *Value, config *Config) bool { func rewriteValueARM_OpZeroExt16to32(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b