mirror of
https://github.com/golang/go.git
synced 2025-10-26 14:24:14 +00:00
cmd/compile: add math/bits.{Add,Sub}64 intrinsics on s390x
This CL adds intrinsics for the 64-bit addition and subtraction functions in math/bits. These intrinsics use the condition code to propagate the carry or borrow bit. To make the carry chains more efficient I've removed the 'clobberFlags' property from most of the load and store operations. Originally these ops did clobber flags when using offsets that didn't fit in a signed 20-bit integer, however that is no longer true. As with other platforms the intrinsics are faster when executed in a chain rather than a loop because currently we need to spill and restore the carry bit between each loop iteration. We may be able to reduce the need to do this on s390x (e.g. by using compare-and-branch instructions that do not clobber flags) in the future. name old time/op new time/op delta Add64 1.21ns ± 2% 2.03ns ± 2% +67.18% (p=0.000 n=7+10) Add64multiple 2.98ns ± 3% 1.03ns ± 0% -65.39% (p=0.000 n=10+9) Sub64 1.23ns ± 4% 2.03ns ± 1% +64.85% (p=0.000 n=10+10) Sub64multiple 3.73ns ± 4% 1.04ns ± 1% -72.28% (p=0.000 n=10+8) Change-Id: I913bbd5e19e6b95bef52f5bc4f14d6fe40119083 Reviewed-on: https://go-review.googlesource.com/c/go/+/174303 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
004fb5cb8d
commit
2c1b5130aa
9 changed files with 880 additions and 195 deletions
1
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
1
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
|
|
@ -66,6 +66,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
ADD $32768, R1, R2 // b9040021c22800008000
|
ADD $32768, R1, R2 // b9040021c22800008000
|
||||||
ADDC R1, R2 // b9ea1022
|
ADDC R1, R2 // b9ea1022
|
||||||
ADDC $1, R1, R2 // ec21000100db
|
ADDC $1, R1, R2 // ec21000100db
|
||||||
|
ADDC $-1, R1, R2 // ec21ffff00db
|
||||||
ADDC R1, R2, R3 // b9ea1032
|
ADDC R1, R2, R3 // b9ea1032
|
||||||
ADDW R1, R2 // 1a21
|
ADDW R1, R2 // 1a21
|
||||||
ADDW R1, R2, R3 // b9f81032
|
ADDW R1, R2, R3 // b9f81032
|
||||||
|
|
|
||||||
|
|
@ -3575,14 +3575,14 @@ func init() {
|
||||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||||
return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
|
return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
|
||||||
},
|
},
|
||||||
sys.AMD64, sys.ARM64, sys.PPC64)
|
sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X)
|
||||||
alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64)
|
alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchS390X)
|
||||||
addF("math/bits", "Sub64",
|
addF("math/bits", "Sub64",
|
||||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||||
return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
|
return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
|
||||||
},
|
},
|
||||||
sys.AMD64, sys.ARM64)
|
sys.AMD64, sys.ARM64, sys.S390X)
|
||||||
alias("math/bits", "Sub", "math/bits", "Sub64", sys.ArchAMD64, sys.ArchARM64)
|
alias("math/bits", "Sub", "math/bits", "Sub64", sys.ArchAMD64, sys.ArchARM64, sys.ArchS390X)
|
||||||
addF("math/bits", "Div64",
|
addF("math/bits", "Div64",
|
||||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||||
// check for divide-by-zero/overflow and panic with appropriate message
|
// check for divide-by-zero/overflow and panic with appropriate message
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,37 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if r != r1 {
|
if r != r1 {
|
||||||
p.Reg = r1
|
p.Reg = r1
|
||||||
}
|
}
|
||||||
|
case ssa.OpS390XADDC:
|
||||||
|
r1 := v.Reg0()
|
||||||
|
r2 := v.Args[0].Reg()
|
||||||
|
r3 := v.Args[1].Reg()
|
||||||
|
if r1 == r2 {
|
||||||
|
r2, r3 = r3, r2
|
||||||
|
}
|
||||||
|
p := opregreg(s, v.Op.Asm(), r1, r2)
|
||||||
|
if r3 != r1 {
|
||||||
|
p.Reg = r3
|
||||||
|
}
|
||||||
|
case ssa.OpS390XSUBC:
|
||||||
|
r1 := v.Reg0()
|
||||||
|
r2 := v.Args[0].Reg()
|
||||||
|
r3 := v.Args[1].Reg()
|
||||||
|
p := opregreg(s, v.Op.Asm(), r1, r3)
|
||||||
|
if r1 != r2 {
|
||||||
|
p.Reg = r2
|
||||||
|
}
|
||||||
|
case ssa.OpS390XADDE, ssa.OpS390XSUBE:
|
||||||
|
r1 := v.Reg0()
|
||||||
|
if r1 != v.Args[0].Reg() {
|
||||||
|
v.Fatalf("input[0] and output not in same register %s", v.LongString())
|
||||||
|
}
|
||||||
|
r2 := v.Args[1].Reg()
|
||||||
|
opregreg(s, v.Op.Asm(), r1, r2)
|
||||||
|
case ssa.OpS390XADDCconst:
|
||||||
|
r1 := v.Reg0()
|
||||||
|
r3 := v.Args[0].Reg()
|
||||||
|
i2 := int64(int16(v.AuxInt))
|
||||||
|
opregregimm(s, v.Op.Asm(), r1, r3, i2)
|
||||||
// 2-address opcode arithmetic
|
// 2-address opcode arithmetic
|
||||||
case ssa.OpS390XMULLD, ssa.OpS390XMULLW,
|
case ssa.OpS390XMULLD, ssa.OpS390XMULLW,
|
||||||
ssa.OpS390XMULHD, ssa.OpS390XMULHDU,
|
ssa.OpS390XMULHD, ssa.OpS390XMULHDU,
|
||||||
|
|
@ -553,7 +584,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
case ssa.OpS390XInvertFlags:
|
case ssa.OpS390XInvertFlags:
|
||||||
v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
|
v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
|
||||||
case ssa.OpS390XFlagEQ, ssa.OpS390XFlagLT, ssa.OpS390XFlagGT:
|
case ssa.OpS390XFlagEQ, ssa.OpS390XFlagLT, ssa.OpS390XFlagGT, ssa.OpS390XFlagOV:
|
||||||
v.Fatalf("Flag* ops should never make it to codegen %v", v.LongString())
|
v.Fatalf("Flag* ops should never make it to codegen %v", v.LongString())
|
||||||
case ssa.OpS390XAddTupleFirst32, ssa.OpS390XAddTupleFirst64:
|
case ssa.OpS390XAddTupleFirst32, ssa.OpS390XAddTupleFirst64:
|
||||||
v.Fatalf("AddTupleFirst* should never make it to codegen %v", v.LongString())
|
v.Fatalf("AddTupleFirst* should never make it to codegen %v", v.LongString())
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,18 @@
|
||||||
(Bswap64 x) -> (MOVDBR x)
|
(Bswap64 x) -> (MOVDBR x)
|
||||||
(Bswap32 x) -> (MOVWBR x)
|
(Bswap32 x) -> (MOVWBR x)
|
||||||
|
|
||||||
|
// add with carry
|
||||||
|
(Select0 (Add64carry x y c))
|
||||||
|
-> (Select0 <typ.UInt64> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))
|
||||||
|
(Select1 (Add64carry x y c))
|
||||||
|
-> (Select0 <typ.UInt64> (ADDE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))))
|
||||||
|
|
||||||
|
// subtract with borrow
|
||||||
|
(Select0 (Sub64borrow x y c))
|
||||||
|
-> (Select0 <typ.UInt64> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c))))
|
||||||
|
(Select1 (Sub64borrow x y c))
|
||||||
|
-> (NEG (Select0 <typ.UInt64> (SUBE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c)))))))
|
||||||
|
|
||||||
// math package intrinsics
|
// math package intrinsics
|
||||||
(Sqrt x) -> (FSQRT x)
|
(Sqrt x) -> (FSQRT x)
|
||||||
(Floor x) -> (FIDBR [7] x)
|
(Floor x) -> (FIDBR [7] x)
|
||||||
|
|
@ -1121,6 +1133,43 @@
|
||||||
(MOVBreg (ANDWconst [m] x)) && int8(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
|
(MOVBreg (ANDWconst [m] x)) && int8(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
|
||||||
(MOVHreg (ANDWconst [m] x)) && int16(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
|
(MOVHreg (ANDWconst [m] x)) && int16(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
|
||||||
|
|
||||||
|
// carry flag generation
|
||||||
|
// (only constant fold carry of zero)
|
||||||
|
(Select1 (ADDCconst (MOVDconst [c]) [d]))
|
||||||
|
&& uint64(c+d) >= uint64(c) && c+d == 0
|
||||||
|
-> (FlagEQ)
|
||||||
|
(Select1 (ADDCconst (MOVDconst [c]) [d]))
|
||||||
|
&& uint64(c+d) >= uint64(c) && c+d != 0
|
||||||
|
-> (FlagLT)
|
||||||
|
|
||||||
|
// borrow flag generation
|
||||||
|
// (only constant fold borrow of zero)
|
||||||
|
(Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
|
||||||
|
&& uint64(d) <= uint64(c) && c-d == 0
|
||||||
|
-> (FlagGT)
|
||||||
|
(Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
|
||||||
|
&& uint64(d) <= uint64(c) && c-d != 0
|
||||||
|
-> (FlagOV)
|
||||||
|
|
||||||
|
// add with carry
|
||||||
|
(ADDE x y (FlagEQ)) -> (ADDC x y)
|
||||||
|
(ADDE x y (FlagLT)) -> (ADDC x y)
|
||||||
|
(ADDC x (MOVDconst [c])) && is16Bit(c) -> (ADDCconst x [c])
|
||||||
|
(Select0 (ADDCconst (MOVDconst [c]) [d])) -> (MOVDconst [c+d])
|
||||||
|
|
||||||
|
// subtract with borrow
|
||||||
|
(SUBE x y (FlagGT)) -> (SUBC x y)
|
||||||
|
(SUBE x y (FlagOV)) -> (SUBC x y)
|
||||||
|
(Select0 (SUBC (MOVDconst [c]) (MOVDconst [d]))) -> (MOVDconst [c-d])
|
||||||
|
|
||||||
|
// collapse carry chain
|
||||||
|
(ADDE x y (Select1 (ADDCconst [-1] (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) c)))))
|
||||||
|
-> (ADDE x y c)
|
||||||
|
|
||||||
|
// collapse borrow chain
|
||||||
|
(SUBE x y (Select1 (SUBC (MOVDconst [0]) (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) c))))))
|
||||||
|
-> (SUBE x y c)
|
||||||
|
|
||||||
// fused multiply-add
|
// fused multiply-add
|
||||||
(FADD (FMUL y z) x) -> (FMADD x y z)
|
(FADD (FMUL y z) x) -> (FMADD x y z)
|
||||||
(FADDS (FMULS y z) x) -> (FMADDS x y z)
|
(FADDS (FMULS y z) x) -> (FMADDS x y z)
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,9 @@ func init() {
|
||||||
gp2flags = regInfo{inputs: []regMask{gpsp, gpsp}}
|
gp2flags = regInfo{inputs: []regMask{gpsp, gpsp}}
|
||||||
gp1flags = regInfo{inputs: []regMask{gpsp}}
|
gp1flags = regInfo{inputs: []regMask{gpsp}}
|
||||||
gp2flags1 = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
|
gp2flags1 = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
|
||||||
|
gp11flags = regInfo{inputs: []regMask{gp}, outputs: gponly}
|
||||||
|
gp21flags = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
|
||||||
|
gp2flags1flags = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
|
||||||
|
|
||||||
gpload = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: gponly}
|
gpload = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: gponly}
|
||||||
gploadidx = regInfo{inputs: []regMask{ptrspsb, ptrsp, 0}, outputs: gponly}
|
gploadidx = regInfo{inputs: []regMask{ptrspsb, ptrsp, 0}, outputs: gponly}
|
||||||
|
|
@ -294,6 +297,17 @@ func init() {
|
||||||
{name: "XORload", argLength: 3, reg: gpopload, asm: "XOR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ *arg1. arg2=mem
|
{name: "XORload", argLength: 3, reg: gpopload, asm: "XOR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ *arg1. arg2=mem
|
||||||
{name: "XORWload", argLength: 3, reg: gpopload, asm: "XORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ *arg1. arg2=mem
|
{name: "XORWload", argLength: 3, reg: gpopload, asm: "XORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ *arg1. arg2=mem
|
||||||
|
|
||||||
|
// Arithmetic ops with carry/borrow chain.
|
||||||
|
//
|
||||||
|
// A carry is represented by a condition code of 2 or 3 (GT or OV).
|
||||||
|
// A borrow is represented by a condition code of 0 or 1 (EQ or LT).
|
||||||
|
{name: "ADDC", argLength: 2, reg: gp21flags, asm: "ADDC", typ: "(UInt64,Flags)", commutative: true}, // (arg0 + arg1, carry out)
|
||||||
|
{name: "ADDCconst", argLength: 1, reg: gp11flags, asm: "ADDC", typ: "(UInt64,Flags)", aux: "Int16"}, // (arg0 + auxint, carry out)
|
||||||
|
{name: "ADDE", argLength: 3, reg: gp2flags1flags, asm: "ADDE", typ: "(UInt64,Flags)", commutative: true, resultInArg0: true}, // (arg0 + arg1 + arg2 (carry in), carry out)
|
||||||
|
{name: "SUBC", argLength: 2, reg: gp21flags, asm: "SUBC", typ: "(UInt64,Flags)"}, // (arg0 - arg1, borrow out)
|
||||||
|
{name: "SUBE", argLength: 3, reg: gp2flags1flags, asm: "SUBE", typ: "(UInt64,Flags)", resultInArg0: true}, // (arg0 - arg1 - arg2 (borrow in), borrow out)
|
||||||
|
|
||||||
|
// Comparisons.
|
||||||
{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1
|
{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1
|
||||||
{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
|
{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
|
||||||
|
|
||||||
|
|
@ -380,49 +394,49 @@ func init() {
|
||||||
{name: "MOVDaddridx", argLength: 2, reg: addridx, aux: "SymOff", symEffect: "Read"}, // arg0 + arg1 + auxint + aux
|
{name: "MOVDaddridx", argLength: 2, reg: addridx, aux: "SymOff", symEffect: "Read"}, // arg0 + arg1 + auxint + aux
|
||||||
|
|
||||||
// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
|
// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
|
||||||
{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // load byte from arg0+auxint+aux. arg1=mem. Zero extend.
|
{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"}, // load byte from arg0+auxint+aux. arg1=mem. Zero extend.
|
||||||
{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // ditto, sign extend to int64
|
{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // ditto, sign extend to int64
|
||||||
{name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem. Zero extend.
|
{name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem. Zero extend.
|
||||||
{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // ditto, sign extend to int64
|
{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // ditto, sign extend to int64
|
||||||
{name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem. Zero extend.
|
{name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem. Zero extend.
|
||||||
{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // ditto, sign extend to int64
|
{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // ditto, sign extend to int64
|
||||||
{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "UInt64", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes from arg0+auxint+aux. arg1=mem
|
{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes from arg0+auxint+aux. arg1=mem
|
||||||
|
|
||||||
{name: "MOVWBR", argLength: 1, reg: gp11, asm: "MOVWBR"}, // arg0 swap bytes
|
{name: "MOVWBR", argLength: 1, reg: gp11, asm: "MOVWBR"}, // arg0 swap bytes
|
||||||
{name: "MOVDBR", argLength: 1, reg: gp11, asm: "MOVDBR"}, // arg0 swap bytes
|
{name: "MOVDBR", argLength: 1, reg: gp11, asm: "MOVDBR"}, // arg0 swap bytes
|
||||||
|
|
||||||
{name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "UInt16", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
|
{name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
|
||||||
{name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "UInt32", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
|
{name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
|
||||||
{name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "UInt64", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
|
{name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
|
||||||
|
|
||||||
{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // store byte in arg1 to arg0+auxint+aux. arg2=mem
|
{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store byte in arg1 to arg0+auxint+aux. arg2=mem
|
||||||
{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
|
{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
|
||||||
{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
|
{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
|
||||||
{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
|
{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
|
||||||
{name: "MOVHBRstore", argLength: 3, reg: gpstorebr, asm: "MOVHBR", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
|
{name: "MOVHBRstore", argLength: 3, reg: gpstorebr, asm: "MOVHBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
|
||||||
{name: "MOVWBRstore", argLength: 3, reg: gpstorebr, asm: "MOVWBR", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
|
{name: "MOVWBRstore", argLength: 3, reg: gpstorebr, asm: "MOVWBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
|
||||||
{name: "MOVDBRstore", argLength: 3, reg: gpstorebr, asm: "MOVDBR", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
|
{name: "MOVDBRstore", argLength: 3, reg: gpstorebr, asm: "MOVDBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
|
||||||
|
|
||||||
{name: "MVC", argLength: 3, reg: gpmvc, asm: "MVC", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, faultOnNilArg1: true, symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size,off
|
{name: "MVC", argLength: 3, reg: gpmvc, asm: "MVC", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, faultOnNilArg1: true, symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size,off
|
||||||
|
|
||||||
// indexed loads/stores
|
// indexed loads/stores
|
||||||
{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", clobberFlags: true, symEffect: "Read"}, // load a byte from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
|
{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", symEffect: "Read"}, // load a byte from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
|
||||||
{name: "MOVBloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVB", aux: "SymOff", typ: "Int8", clobberFlags: true, symEffect: "Read"}, // load a byte from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
|
{name: "MOVBloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVB", aux: "SymOff", typ: "Int8", symEffect: "Read"}, // load a byte from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
|
||||||
{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", clobberFlags: true, symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
|
{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
|
||||||
{name: "MOVHloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVH", aux: "SymOff", typ: "Int16", clobberFlags: true, symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
|
{name: "MOVHloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVH", aux: "SymOff", typ: "Int16", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
|
||||||
{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", clobberFlags: true, symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
|
{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
|
||||||
{name: "MOVWloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVW", aux: "SymOff", typ: "Int32", clobberFlags: true, symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
|
{name: "MOVWloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVW", aux: "SymOff", typ: "Int32", symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
|
||||||
{name: "MOVDloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVD", aux: "SymOff", typ: "UInt64", clobberFlags: true, symEffect: "Read"}, // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem
|
{name: "MOVDloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVD", aux: "SymOff", typ: "UInt64", symEffect: "Read"}, // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem
|
||||||
{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHBR", aux: "SymOff", typ: "Int16", clobberFlags: true, symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
|
{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHBR", aux: "SymOff", typ: "Int16", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
|
||||||
{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWBR", aux: "SymOff", typ: "Int32", clobberFlags: true, symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
|
{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWBR", aux: "SymOff", typ: "Int32", symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
|
||||||
{name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVDBR", aux: "SymOff", typ: "Int64", clobberFlags: true, symEffect: "Read"}, // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
|
{name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVDBR", aux: "SymOff", typ: "Int64", symEffect: "Read"}, // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
|
||||||
{name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", aux: "SymOff", clobberFlags: true, symEffect: "Write"}, // store byte in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
{name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", aux: "SymOff", symEffect: "Write"}, // store byte in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
||||||
{name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVH", aux: "SymOff", clobberFlags: true, symEffect: "Write"}, // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
{name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVH", aux: "SymOff", symEffect: "Write"}, // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
||||||
{name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", aux: "SymOff", clobberFlags: true, symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
{name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
||||||
{name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVD", aux: "SymOff", clobberFlags: true, symEffect: "Write"}, // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
{name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVD", aux: "SymOff", symEffect: "Write"}, // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
|
||||||
{name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVHBR", aux: "SymOff", clobberFlags: true, symEffect: "Write"}, // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
|
{name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVHBR", aux: "SymOff", symEffect: "Write"}, // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
|
||||||
{name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVWBR", aux: "SymOff", clobberFlags: true, symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
|
{name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVWBR", aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
|
||||||
{name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVDBR", aux: "SymOff", clobberFlags: true, symEffect: "Write"}, // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
|
{name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVDBR", aux: "SymOff", symEffect: "Write"}, // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
|
||||||
|
|
||||||
// For storeconst ops, the AuxInt field encodes both
|
// For storeconst ops, the AuxInt field encodes both
|
||||||
// the value to store and an address offset of the store.
|
// the value to store and an address offset of the store.
|
||||||
|
|
@ -473,16 +487,11 @@ func init() {
|
||||||
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
|
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
|
||||||
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
|
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
|
||||||
|
|
||||||
// Constant flag values. For any comparison, there are 5 possible
|
// Constant conditon code values. The condition code can be 0, 1, 2 or 3.
|
||||||
// outcomes: the three from the signed total order (<,==,>) and the
|
{name: "FlagEQ"}, // CC=0 (equal)
|
||||||
// three from the unsigned total order. The == cases overlap.
|
{name: "FlagLT"}, // CC=1 (less than)
|
||||||
// Note: there's a sixth "unordered" outcome for floating-point
|
{name: "FlagGT"}, // CC=2 (greater than)
|
||||||
// comparisons, but we don't use such a beast yet.
|
{name: "FlagOV"}, // CC=3 (overflow)
|
||||||
// These ops are for temporary use by rewrite rules. They
|
|
||||||
// cannot appear in the generated assembly.
|
|
||||||
{name: "FlagEQ"}, // equal
|
|
||||||
{name: "FlagLT"}, // <
|
|
||||||
{name: "FlagGT"}, // >
|
|
||||||
|
|
||||||
// Atomic loads. These are just normal loads but return <value,memory> tuples
|
// Atomic loads. These are just normal loads but return <value,memory> tuples
|
||||||
// so they can be properly ordered with other loads.
|
// so they can be properly ordered with other loads.
|
||||||
|
|
|
||||||
|
|
@ -1922,6 +1922,11 @@ const (
|
||||||
OpS390XXORWconst
|
OpS390XXORWconst
|
||||||
OpS390XXORload
|
OpS390XXORload
|
||||||
OpS390XXORWload
|
OpS390XXORWload
|
||||||
|
OpS390XADDC
|
||||||
|
OpS390XADDCconst
|
||||||
|
OpS390XADDE
|
||||||
|
OpS390XSUBC
|
||||||
|
OpS390XSUBE
|
||||||
OpS390XCMP
|
OpS390XCMP
|
||||||
OpS390XCMPW
|
OpS390XCMPW
|
||||||
OpS390XCMPU
|
OpS390XCMPU
|
||||||
|
|
@ -2044,6 +2049,7 @@ const (
|
||||||
OpS390XFlagEQ
|
OpS390XFlagEQ
|
||||||
OpS390XFlagLT
|
OpS390XFlagLT
|
||||||
OpS390XFlagGT
|
OpS390XFlagGT
|
||||||
|
OpS390XFlagOV
|
||||||
OpS390XMOVWZatomicload
|
OpS390XMOVWZatomicload
|
||||||
OpS390XMOVDatomicload
|
OpS390XMOVDatomicload
|
||||||
OpS390XMOVWatomicstore
|
OpS390XMOVWatomicstore
|
||||||
|
|
@ -25811,6 +25817,80 @@ var opcodeTable = [...]opInfo{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ADDC",
|
||||||
|
argLen: 2,
|
||||||
|
commutative: true,
|
||||||
|
asm: s390x.AADDC,
|
||||||
|
reg: regInfo{
|
||||||
|
inputs: []inputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
{1, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
outputs: []outputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ADDCconst",
|
||||||
|
auxType: auxInt16,
|
||||||
|
argLen: 1,
|
||||||
|
asm: s390x.AADDC,
|
||||||
|
reg: regInfo{
|
||||||
|
inputs: []inputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
outputs: []outputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ADDE",
|
||||||
|
argLen: 3,
|
||||||
|
commutative: true,
|
||||||
|
resultInArg0: true,
|
||||||
|
asm: s390x.AADDE,
|
||||||
|
reg: regInfo{
|
||||||
|
inputs: []inputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
{1, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
outputs: []outputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SUBC",
|
||||||
|
argLen: 2,
|
||||||
|
asm: s390x.ASUBC,
|
||||||
|
reg: regInfo{
|
||||||
|
inputs: []inputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
{1, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
outputs: []outputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SUBE",
|
||||||
|
argLen: 3,
|
||||||
|
resultInArg0: true,
|
||||||
|
asm: s390x.ASUBE,
|
||||||
|
reg: regInfo{
|
||||||
|
inputs: []inputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
{1, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
outputs: []outputInfo{
|
||||||
|
{0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "CMP",
|
name: "CMP",
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
|
|
@ -26644,7 +26724,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVBZload",
|
name: "MOVBZload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVBZ,
|
asm: s390x.AMOVBZ,
|
||||||
|
|
@ -26661,7 +26740,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVBload",
|
name: "MOVBload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVB,
|
asm: s390x.AMOVB,
|
||||||
|
|
@ -26678,7 +26756,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVHZload",
|
name: "MOVHZload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVHZ,
|
asm: s390x.AMOVHZ,
|
||||||
|
|
@ -26695,7 +26772,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVHload",
|
name: "MOVHload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVH,
|
asm: s390x.AMOVH,
|
||||||
|
|
@ -26712,7 +26788,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVWZload",
|
name: "MOVWZload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVWZ,
|
asm: s390x.AMOVWZ,
|
||||||
|
|
@ -26729,7 +26804,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVWload",
|
name: "MOVWload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVW,
|
asm: s390x.AMOVW,
|
||||||
|
|
@ -26746,7 +26820,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVDload",
|
name: "MOVDload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVD,
|
asm: s390x.AMOVD,
|
||||||
|
|
@ -26789,7 +26862,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVHBRload",
|
name: "MOVHBRload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVHBR,
|
asm: s390x.AMOVHBR,
|
||||||
|
|
@ -26806,7 +26878,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVWBRload",
|
name: "MOVWBRload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVWBR,
|
asm: s390x.AMOVWBR,
|
||||||
|
|
@ -26823,7 +26894,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVDBRload",
|
name: "MOVDBRload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 2,
|
argLen: 2,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVDBR,
|
asm: s390x.AMOVDBR,
|
||||||
|
|
@ -26840,7 +26910,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVBstore",
|
name: "MOVBstore",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVB,
|
asm: s390x.AMOVB,
|
||||||
|
|
@ -26855,7 +26924,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVHstore",
|
name: "MOVHstore",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVH,
|
asm: s390x.AMOVH,
|
||||||
|
|
@ -26870,7 +26938,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVWstore",
|
name: "MOVWstore",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVW,
|
asm: s390x.AMOVW,
|
||||||
|
|
@ -26885,7 +26952,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVDstore",
|
name: "MOVDstore",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVD,
|
asm: s390x.AMOVD,
|
||||||
|
|
@ -26900,7 +26966,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVHBRstore",
|
name: "MOVHBRstore",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVHBR,
|
asm: s390x.AMOVHBR,
|
||||||
|
|
@ -26915,7 +26980,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVWBRstore",
|
name: "MOVWBRstore",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVWBR,
|
asm: s390x.AMOVWBR,
|
||||||
|
|
@ -26930,7 +26994,6 @@ var opcodeTable = [...]opInfo{
|
||||||
name: "MOVDBRstore",
|
name: "MOVDBRstore",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
clobberFlags: true,
|
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVDBR,
|
asm: s390x.AMOVDBR,
|
||||||
|
|
@ -26962,7 +27025,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVBZ,
|
asm: s390x.AMOVBZ,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -26980,7 +27042,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVB,
|
asm: s390x.AMOVB,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -26998,7 +27059,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVHZ,
|
asm: s390x.AMOVHZ,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27016,7 +27076,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVH,
|
asm: s390x.AMOVH,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27034,7 +27093,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVWZ,
|
asm: s390x.AMOVWZ,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27052,7 +27110,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVW,
|
asm: s390x.AMOVW,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27070,7 +27127,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVD,
|
asm: s390x.AMOVD,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27088,7 +27144,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVHBR,
|
asm: s390x.AMOVHBR,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27106,7 +27161,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVWBR,
|
asm: s390x.AMOVWBR,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27124,7 +27178,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymRead,
|
symEffect: SymRead,
|
||||||
asm: s390x.AMOVDBR,
|
asm: s390x.AMOVDBR,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27142,7 +27195,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVB,
|
asm: s390x.AMOVB,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27158,7 +27210,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVH,
|
asm: s390x.AMOVH,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27174,7 +27225,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVW,
|
asm: s390x.AMOVW,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27190,7 +27240,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVD,
|
asm: s390x.AMOVD,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27206,7 +27255,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVHBR,
|
asm: s390x.AMOVHBR,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27222,7 +27270,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVWBR,
|
asm: s390x.AMOVWBR,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27238,7 +27285,6 @@ var opcodeTable = [...]opInfo{
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
argLen: 4,
|
argLen: 4,
|
||||||
commutative: true,
|
commutative: true,
|
||||||
clobberFlags: true,
|
|
||||||
symEffect: SymWrite,
|
symEffect: SymWrite,
|
||||||
asm: s390x.AMOVDBR,
|
asm: s390x.AMOVDBR,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
|
|
@ -27499,6 +27545,11 @@ var opcodeTable = [...]opInfo{
|
||||||
argLen: 0,
|
argLen: 0,
|
||||||
reg: regInfo{},
|
reg: regInfo{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "FlagOV",
|
||||||
|
argLen: 0,
|
||||||
|
reg: regInfo{},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "MOVWZatomicload",
|
name: "MOVWZatomicload",
|
||||||
auxType: auxSymOff,
|
auxType: auxSymOff,
|
||||||
|
|
|
||||||
|
|
@ -477,6 +477,10 @@ func rewriteValueS390X(v *Value) bool {
|
||||||
return rewriteValueS390X_OpRsh8x8_0(v)
|
return rewriteValueS390X_OpRsh8x8_0(v)
|
||||||
case OpS390XADD:
|
case OpS390XADD:
|
||||||
return rewriteValueS390X_OpS390XADD_0(v) || rewriteValueS390X_OpS390XADD_10(v)
|
return rewriteValueS390X_OpS390XADD_0(v) || rewriteValueS390X_OpS390XADD_10(v)
|
||||||
|
case OpS390XADDC:
|
||||||
|
return rewriteValueS390X_OpS390XADDC_0(v)
|
||||||
|
case OpS390XADDE:
|
||||||
|
return rewriteValueS390X_OpS390XADDE_0(v)
|
||||||
case OpS390XADDW:
|
case OpS390XADDW:
|
||||||
return rewriteValueS390X_OpS390XADDW_0(v) || rewriteValueS390X_OpS390XADDW_10(v)
|
return rewriteValueS390X_OpS390XADDW_0(v) || rewriteValueS390X_OpS390XADDW_10(v)
|
||||||
case OpS390XADDWconst:
|
case OpS390XADDWconst:
|
||||||
|
|
@ -705,6 +709,8 @@ func rewriteValueS390X(v *Value) bool {
|
||||||
return rewriteValueS390X_OpS390XSTMG2_0(v)
|
return rewriteValueS390X_OpS390XSTMG2_0(v)
|
||||||
case OpS390XSUB:
|
case OpS390XSUB:
|
||||||
return rewriteValueS390X_OpS390XSUB_0(v)
|
return rewriteValueS390X_OpS390XSUB_0(v)
|
||||||
|
case OpS390XSUBE:
|
||||||
|
return rewriteValueS390X_OpS390XSUBE_0(v)
|
||||||
case OpS390XSUBW:
|
case OpS390XSUBW:
|
||||||
return rewriteValueS390X_OpS390XSUBW_0(v)
|
return rewriteValueS390X_OpS390XSUBW_0(v)
|
||||||
case OpS390XSUBWconst:
|
case OpS390XSUBWconst:
|
||||||
|
|
@ -6849,6 +6855,175 @@ func rewriteValueS390X_OpS390XADD_10(v *Value) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
func rewriteValueS390X_OpS390XADDC_0(v *Value) bool {
|
||||||
|
// match: (ADDC x (MOVDconst [c]))
|
||||||
|
// cond: is16Bit(c)
|
||||||
|
// result: (ADDCconst x [c])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
x := v.Args[0]
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_1.AuxInt
|
||||||
|
if !(is16Bit(c)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XADDCconst)
|
||||||
|
v.AuxInt = c
|
||||||
|
v.AddArg(x)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (ADDC (MOVDconst [c]) x)
|
||||||
|
// cond: is16Bit(c)
|
||||||
|
// result: (ADDCconst x [c])
|
||||||
|
for {
|
||||||
|
x := v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0.AuxInt
|
||||||
|
if !(is16Bit(c)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XADDCconst)
|
||||||
|
v.AuxInt = c
|
||||||
|
v.AddArg(x)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteValueS390X_OpS390XADDE_0(v *Value) bool {
|
||||||
|
// match: (ADDE x y (FlagEQ))
|
||||||
|
// cond:
|
||||||
|
// result: (ADDC x y)
|
||||||
|
for {
|
||||||
|
_ = v.Args[2]
|
||||||
|
x := v.Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
if v_2.Op != OpS390XFlagEQ {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XADDC)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (ADDE x y (FlagLT))
|
||||||
|
// cond:
|
||||||
|
// result: (ADDC x y)
|
||||||
|
for {
|
||||||
|
_ = v.Args[2]
|
||||||
|
x := v.Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
if v_2.Op != OpS390XFlagLT {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XADDC)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (ADDE x y (Select1 (ADDCconst [-1] (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) c)))))
|
||||||
|
// cond:
|
||||||
|
// result: (ADDE x y c)
|
||||||
|
for {
|
||||||
|
_ = v.Args[2]
|
||||||
|
x := v.Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
if v_2.Op != OpSelect1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0 := v_2.Args[0]
|
||||||
|
if v_2_0.Op != OpS390XADDCconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0.AuxInt != -1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_0 := v_2_0.Args[0]
|
||||||
|
if v_2_0_0.Op != OpSelect0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_0_0 := v_2_0_0.Args[0]
|
||||||
|
if v_2_0_0_0.Op != OpS390XADDE {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_2_0_0_0.Args[2]
|
||||||
|
v_2_0_0_0_0 := v_2_0_0_0.Args[0]
|
||||||
|
if v_2_0_0_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0_0_0_0.AuxInt != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_0_0_1 := v_2_0_0_0.Args[1]
|
||||||
|
if v_2_0_0_0_1.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0_0_0_1.AuxInt != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XADDE)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
v.AddArg(c)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (ADDE x y (Select1 (ADDCconst [-1] (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) c)))))
|
||||||
|
// cond:
|
||||||
|
// result: (ADDE x y c)
|
||||||
|
for {
|
||||||
|
_ = v.Args[2]
|
||||||
|
x := v.Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
if v_2.Op != OpSelect1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0 := v_2.Args[0]
|
||||||
|
if v_2_0.Op != OpS390XADDCconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0.AuxInt != -1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_0 := v_2_0.Args[0]
|
||||||
|
if v_2_0_0.Op != OpSelect0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_0_0 := v_2_0_0.Args[0]
|
||||||
|
if v_2_0_0_0.Op != OpS390XADDE {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_2_0_0_0.Args[2]
|
||||||
|
v_2_0_0_0_0 := v_2_0_0_0.Args[0]
|
||||||
|
if v_2_0_0_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0_0_0_0.AuxInt != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_0_0_1 := v_2_0_0_0.Args[1]
|
||||||
|
if v_2_0_0_0_1.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0_0_0_1.AuxInt != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XADDE)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
v.AddArg(c)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
func rewriteValueS390X_OpS390XADDW_0(v *Value) bool {
|
func rewriteValueS390X_OpS390XADDW_0(v *Value) bool {
|
||||||
// match: (ADDW x (MOVDconst [c]))
|
// match: (ADDW x (MOVDconst [c]))
|
||||||
// cond:
|
// cond:
|
||||||
|
|
@ -39017,6 +39192,97 @@ func rewriteValueS390X_OpS390XSUB_0(v *Value) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
func rewriteValueS390X_OpS390XSUBE_0(v *Value) bool {
|
||||||
|
// match: (SUBE x y (FlagGT))
|
||||||
|
// cond:
|
||||||
|
// result: (SUBC x y)
|
||||||
|
for {
|
||||||
|
_ = v.Args[2]
|
||||||
|
x := v.Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
if v_2.Op != OpS390XFlagGT {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XSUBC)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (SUBE x y (FlagOV))
|
||||||
|
// cond:
|
||||||
|
// result: (SUBC x y)
|
||||||
|
for {
|
||||||
|
_ = v.Args[2]
|
||||||
|
x := v.Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
if v_2.Op != OpS390XFlagOV {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XSUBC)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (SUBE x y (Select1 (SUBC (MOVDconst [0]) (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) c))))))
|
||||||
|
// cond:
|
||||||
|
// result: (SUBE x y c)
|
||||||
|
for {
|
||||||
|
_ = v.Args[2]
|
||||||
|
x := v.Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v_2 := v.Args[2]
|
||||||
|
if v_2.Op != OpSelect1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0 := v_2.Args[0]
|
||||||
|
if v_2_0.Op != OpS390XSUBC {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_2_0.Args[1]
|
||||||
|
v_2_0_0 := v_2_0.Args[0]
|
||||||
|
if v_2_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0_0.AuxInt != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_1 := v_2_0.Args[1]
|
||||||
|
if v_2_0_1.Op != OpS390XNEG {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_1_0 := v_2_0_1.Args[0]
|
||||||
|
if v_2_0_1_0.Op != OpSelect0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_1_0_0 := v_2_0_1_0.Args[0]
|
||||||
|
if v_2_0_1_0_0.Op != OpS390XSUBE {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_2_0_1_0_0.Args[2]
|
||||||
|
v_2_0_1_0_0_0 := v_2_0_1_0_0.Args[0]
|
||||||
|
if v_2_0_1_0_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0_1_0_0_0.AuxInt != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_2_0_1_0_0_1 := v_2_0_1_0_0.Args[1]
|
||||||
|
if v_2_0_1_0_0_1.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v_2_0_1_0_0_1.AuxInt != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XSUBE)
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
v.AddArg(c)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
func rewriteValueS390X_OpS390XSUBW_0(v *Value) bool {
|
func rewriteValueS390X_OpS390XSUBW_0(v *Value) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
// match: (SUBW x (MOVDconst [c]))
|
// match: (SUBW x (MOVDconst [c]))
|
||||||
|
|
@ -40180,6 +40446,59 @@ func rewriteValueS390X_OpS390XXORload_0(v *Value) bool {
|
||||||
}
|
}
|
||||||
func rewriteValueS390X_OpSelect0_0(v *Value) bool {
|
func rewriteValueS390X_OpSelect0_0(v *Value) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
|
typ := &b.Func.Config.Types
|
||||||
|
// match: (Select0 (Add64carry x y c))
|
||||||
|
// cond:
|
||||||
|
// result: (Select0 <typ.UInt64> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpAdd64carry {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0.Args[2]
|
||||||
|
x := v_0.Args[0]
|
||||||
|
y := v_0.Args[1]
|
||||||
|
v.reset(OpSelect0)
|
||||||
|
v.Type = typ.UInt64
|
||||||
|
v0 := b.NewValue0(v.Pos, OpS390XADDE, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v0.AddArg(x)
|
||||||
|
v0.AddArg(y)
|
||||||
|
v1 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
|
||||||
|
v2 := b.NewValue0(v.Pos, OpS390XADDCconst, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v2.AuxInt = -1
|
||||||
|
v2.AddArg(c)
|
||||||
|
v1.AddArg(v2)
|
||||||
|
v0.AddArg(v1)
|
||||||
|
v.AddArg(v0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Select0 (Sub64borrow x y c))
|
||||||
|
// cond:
|
||||||
|
// result: (Select0 <typ.UInt64> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c))))
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpSub64borrow {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0.Args[2]
|
||||||
|
x := v_0.Args[0]
|
||||||
|
y := v_0.Args[1]
|
||||||
|
v.reset(OpSelect0)
|
||||||
|
v.Type = typ.UInt64
|
||||||
|
v0 := b.NewValue0(v.Pos, OpS390XSUBE, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v0.AddArg(x)
|
||||||
|
v0.AddArg(y)
|
||||||
|
v1 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
|
||||||
|
v2 := b.NewValue0(v.Pos, OpS390XSUBC, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v3 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
|
||||||
|
v3.AuxInt = 0
|
||||||
|
v2.AddArg(v3)
|
||||||
|
v2.AddArg(c)
|
||||||
|
v1.AddArg(v2)
|
||||||
|
v0.AddArg(v1)
|
||||||
|
v.AddArg(v0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
// match: (Select0 <t> (AddTupleFirst32 val tuple))
|
// match: (Select0 <t> (AddTupleFirst32 val tuple))
|
||||||
// cond:
|
// cond:
|
||||||
// result: (ADDW val (Select0 <t> tuple))
|
// result: (ADDW val (Select0 <t> tuple))
|
||||||
|
|
@ -40216,9 +40535,125 @@ func rewriteValueS390X_OpSelect0_0(v *Value) bool {
|
||||||
v.AddArg(v0)
|
v.AddArg(v0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// match: (Select0 (ADDCconst (MOVDconst [c]) [d]))
|
||||||
|
// cond:
|
||||||
|
// result: (MOVDconst [c+d])
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpS390XADDCconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_0.AuxInt
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0.AuxInt
|
||||||
|
v.reset(OpS390XMOVDconst)
|
||||||
|
v.AuxInt = c + d
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Select0 (SUBC (MOVDconst [c]) (MOVDconst [d])))
|
||||||
|
// cond:
|
||||||
|
// result: (MOVDconst [c-d])
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpS390XSUBC {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0.AuxInt
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_0_1.AuxInt
|
||||||
|
v.reset(OpS390XMOVDconst)
|
||||||
|
v.AuxInt = c - d
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
func rewriteValueS390X_OpSelect1_0(v *Value) bool {
|
func rewriteValueS390X_OpSelect1_0(v *Value) bool {
|
||||||
|
b := v.Block
|
||||||
|
typ := &b.Func.Config.Types
|
||||||
|
// match: (Select1 (Add64carry x y c))
|
||||||
|
// cond:
|
||||||
|
// result: (Select0 <typ.UInt64> (ADDE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))))
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpAdd64carry {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0.Args[2]
|
||||||
|
x := v_0.Args[0]
|
||||||
|
y := v_0.Args[1]
|
||||||
|
v.reset(OpSelect0)
|
||||||
|
v.Type = typ.UInt64
|
||||||
|
v0 := b.NewValue0(v.Pos, OpS390XADDE, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
|
||||||
|
v1.AuxInt = 0
|
||||||
|
v0.AddArg(v1)
|
||||||
|
v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
|
||||||
|
v2.AuxInt = 0
|
||||||
|
v0.AddArg(v2)
|
||||||
|
v3 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
|
||||||
|
v4 := b.NewValue0(v.Pos, OpS390XADDE, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v4.AddArg(x)
|
||||||
|
v4.AddArg(y)
|
||||||
|
v5 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
|
||||||
|
v6 := b.NewValue0(v.Pos, OpS390XADDCconst, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v6.AuxInt = -1
|
||||||
|
v6.AddArg(c)
|
||||||
|
v5.AddArg(v6)
|
||||||
|
v4.AddArg(v5)
|
||||||
|
v3.AddArg(v4)
|
||||||
|
v0.AddArg(v3)
|
||||||
|
v.AddArg(v0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Select1 (Sub64borrow x y c))
|
||||||
|
// cond:
|
||||||
|
// result: (NEG (Select0 <typ.UInt64> (SUBE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c)))))))
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpSub64borrow {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0.Args[2]
|
||||||
|
x := v_0.Args[0]
|
||||||
|
y := v_0.Args[1]
|
||||||
|
v.reset(OpS390XNEG)
|
||||||
|
v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
|
||||||
|
v1 := b.NewValue0(v.Pos, OpS390XSUBE, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
|
||||||
|
v2.AuxInt = 0
|
||||||
|
v1.AddArg(v2)
|
||||||
|
v3 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
|
||||||
|
v3.AuxInt = 0
|
||||||
|
v1.AddArg(v3)
|
||||||
|
v4 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
|
||||||
|
v5 := b.NewValue0(v.Pos, OpS390XSUBE, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v5.AddArg(x)
|
||||||
|
v5.AddArg(y)
|
||||||
|
v6 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
|
||||||
|
v7 := b.NewValue0(v.Pos, OpS390XSUBC, types.NewTuple(typ.UInt64, types.TypeFlags))
|
||||||
|
v8 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
|
||||||
|
v8.AuxInt = 0
|
||||||
|
v7.AddArg(v8)
|
||||||
|
v7.AddArg(c)
|
||||||
|
v6.AddArg(v7)
|
||||||
|
v5.AddArg(v6)
|
||||||
|
v4.AddArg(v5)
|
||||||
|
v1.AddArg(v4)
|
||||||
|
v0.AddArg(v1)
|
||||||
|
v.AddArg(v0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
// match: (Select1 (AddTupleFirst32 _ tuple))
|
// match: (Select1 (AddTupleFirst32 _ tuple))
|
||||||
// cond:
|
// cond:
|
||||||
// result: (Select1 tuple)
|
// result: (Select1 tuple)
|
||||||
|
|
@ -40245,6 +40680,96 @@ func rewriteValueS390X_OpSelect1_0(v *Value) bool {
|
||||||
v.AddArg(tuple)
|
v.AddArg(tuple)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// match: (Select1 (ADDCconst (MOVDconst [c]) [d]))
|
||||||
|
// cond: uint64(c+d) >= uint64(c) && c+d == 0
|
||||||
|
// result: (FlagEQ)
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpS390XADDCconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_0.AuxInt
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0.AuxInt
|
||||||
|
if !(uint64(c+d) >= uint64(c) && c+d == 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XFlagEQ)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Select1 (ADDCconst (MOVDconst [c]) [d]))
|
||||||
|
// cond: uint64(c+d) >= uint64(c) && c+d != 0
|
||||||
|
// result: (FlagLT)
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpS390XADDCconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_0.AuxInt
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0.AuxInt
|
||||||
|
if !(uint64(c+d) >= uint64(c) && c+d != 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XFlagLT)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
|
||||||
|
// cond: uint64(d) <= uint64(c) && c-d == 0
|
||||||
|
// result: (FlagGT)
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpS390XSUBC {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0.AuxInt
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_0_1.AuxInt
|
||||||
|
if !(uint64(d) <= uint64(c) && c-d == 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XFlagGT)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
|
||||||
|
// cond: uint64(d) <= uint64(c) && c-d != 0
|
||||||
|
// result: (FlagOV)
|
||||||
|
for {
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpS390XSUBC {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0.AuxInt
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpS390XMOVDconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_0_1.AuxInt
|
||||||
|
if !(uint64(d) <= uint64(c) && c-d != 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpS390XFlagOV)
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
func rewriteValueS390X_OpSignExt16to32_0(v *Value) bool {
|
func rewriteValueS390X_OpSignExt16to32_0(v *Value) bool {
|
||||||
|
|
|
||||||
|
|
@ -3139,15 +3139,13 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
|
||||||
}
|
}
|
||||||
r = p.To.Reg
|
r = p.To.Reg
|
||||||
}
|
}
|
||||||
if r == p.To.Reg {
|
if opri != 0 && r == p.To.Reg && int64(int16(v)) == v {
|
||||||
if opri != 0 && int64(int16(v)) == v {
|
|
||||||
zRI(opri, uint32(p.To.Reg), uint32(v), asm)
|
zRI(opri, uint32(p.To.Reg), uint32(v), asm)
|
||||||
|
} else if oprie != 0 && int64(int16(v)) == v {
|
||||||
|
zRIE(_d, oprie, uint32(p.To.Reg), uint32(r), uint32(v), 0, 0, 0, 0, asm)
|
||||||
} else {
|
} else {
|
||||||
zRIL(_a, opril, uint32(p.To.Reg), uint32(v), asm)
|
zRIL(_a, opril, uint32(p.To.Reg), uint32(v), asm)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
zRIE(_d, oprie, uint32(p.To.Reg), uint32(r), uint32(v), 0, 0, 0, 0, asm)
|
|
||||||
}
|
|
||||||
|
|
||||||
case 23: // 64-bit logical op $constant reg
|
case 23: // 64-bit logical op $constant reg
|
||||||
// TODO(mundaym): merge with case 24.
|
// TODO(mundaym): merge with case 24.
|
||||||
|
|
|
||||||
|
|
@ -377,32 +377,38 @@ func IterateBits8(n uint8) int {
|
||||||
func Add(x, y, ci uint) (r, co uint) {
|
func Add(x, y, ci uint) (r, co uint) {
|
||||||
// arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
|
// arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
|
||||||
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
||||||
|
// s390x:"ADDE","ADDC\t[$]-1,"
|
||||||
return bits.Add(x, y, ci)
|
return bits.Add(x, y, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddC(x, ci uint) (r, co uint) {
|
func AddC(x, ci uint) (r, co uint) {
|
||||||
// arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
|
// arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
|
||||||
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
||||||
|
// s390x:"ADDE","ADDC\t[$]-1,"
|
||||||
return bits.Add(x, 7, ci)
|
return bits.Add(x, 7, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddZ(x, y uint) (r, co uint) {
|
func AddZ(x, y uint) (r, co uint) {
|
||||||
// arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
|
// arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
|
||||||
// amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
|
// amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
|
||||||
|
// s390x:"ADDC",-"ADDC\t[$]-1,"
|
||||||
return bits.Add(x, y, 0)
|
return bits.Add(x, y, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddR(x, y, ci uint) uint {
|
func AddR(x, y, ci uint) uint {
|
||||||
// arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
|
// arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
|
||||||
// amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
|
// amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
|
||||||
|
// s390x:"ADDE","ADDC\t[$]-1,"
|
||||||
r, _ := bits.Add(x, y, ci)
|
r, _ := bits.Add(x, y, ci)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddM(p, q, r *[3]uint) {
|
func AddM(p, q, r *[3]uint) {
|
||||||
var c uint
|
var c uint
|
||||||
r[0], c = bits.Add(p[0], q[0], c)
|
r[0], c = bits.Add(p[0], q[0], c)
|
||||||
// arm64:"ADCS",-"ADD\t",-"CMP"
|
// arm64:"ADCS",-"ADD\t",-"CMP"
|
||||||
// amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
|
// amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
|
||||||
|
// s390x:"ADDE",-"ADDC\t[$]-1,"
|
||||||
r[1], c = bits.Add(p[1], q[1], c)
|
r[1], c = bits.Add(p[1], q[1], c)
|
||||||
r[2], c = bits.Add(p[2], q[2], c)
|
r[2], c = bits.Add(p[2], q[2], c)
|
||||||
}
|
}
|
||||||
|
|
@ -412,6 +418,7 @@ func Add64(x, y, ci uint64) (r, co uint64) {
|
||||||
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
||||||
// ppc64: "ADDC", "ADDE", "ADDZE"
|
// ppc64: "ADDC", "ADDE", "ADDZE"
|
||||||
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
||||||
|
// s390x:"ADDE","ADDC\t[$]-1,"
|
||||||
return bits.Add64(x, y, ci)
|
return bits.Add64(x, y, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -420,6 +427,7 @@ func Add64C(x, ci uint64) (r, co uint64) {
|
||||||
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
|
||||||
// ppc64: "ADDC", "ADDE", "ADDZE"
|
// ppc64: "ADDC", "ADDE", "ADDZE"
|
||||||
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
||||||
|
// s390x:"ADDE","ADDC\t[$]-1,"
|
||||||
return bits.Add64(x, 7, ci)
|
return bits.Add64(x, 7, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -428,6 +436,7 @@ func Add64Z(x, y uint64) (r, co uint64) {
|
||||||
// amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
|
// amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
|
||||||
// ppc64: "ADDC", "ADDE", "ADDZE"
|
// ppc64: "ADDC", "ADDE", "ADDZE"
|
||||||
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
||||||
|
// s390x:"ADDC",-"ADDC\t[$]-1,"
|
||||||
return bits.Add64(x, y, 0)
|
return bits.Add64(x, y, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -436,6 +445,7 @@ func Add64R(x, y, ci uint64) uint64 {
|
||||||
// amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
|
// amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
|
||||||
// ppc64: "ADDC", "ADDE", "ADDZE"
|
// ppc64: "ADDC", "ADDE", "ADDZE"
|
||||||
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
||||||
|
// s390x:"ADDE","ADDC\t[$]-1,"
|
||||||
r, _ := bits.Add64(x, y, ci)
|
r, _ := bits.Add64(x, y, ci)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
@ -446,6 +456,7 @@ func Add64M(p, q, r *[3]uint64) {
|
||||||
// amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
|
// amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
|
||||||
// ppc64: "ADDC", "ADDE", "ADDZE"
|
// ppc64: "ADDC", "ADDE", "ADDZE"
|
||||||
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
// ppc64le: "ADDC", "ADDE", "ADDZE"
|
||||||
|
// s390x:"ADDE",-"ADDC\t[$]-1,"
|
||||||
r[1], c = bits.Add64(p[1], q[1], c)
|
r[1], c = bits.Add64(p[1], q[1], c)
|
||||||
r[2], c = bits.Add64(p[2], q[2], c)
|
r[2], c = bits.Add64(p[2], q[2], c)
|
||||||
}
|
}
|
||||||
|
|
@ -457,24 +468,28 @@ func Add64M(p, q, r *[3]uint64) {
|
||||||
func Sub(x, y, ci uint) (r, co uint) {
|
func Sub(x, y, ci uint) (r, co uint) {
|
||||||
// amd64:"NEGL","SBBQ","NEGQ"
|
// amd64:"NEGL","SBBQ","NEGQ"
|
||||||
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
return bits.Sub(x, y, ci)
|
return bits.Sub(x, y, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SubC(x, ci uint) (r, co uint) {
|
func SubC(x, ci uint) (r, co uint) {
|
||||||
// amd64:"NEGL","SBBQ","NEGQ"
|
// amd64:"NEGL","SBBQ","NEGQ"
|
||||||
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
return bits.Sub(x, 7, ci)
|
return bits.Sub(x, 7, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SubZ(x, y uint) (r, co uint) {
|
func SubZ(x, y uint) (r, co uint) {
|
||||||
// amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
|
// amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
|
||||||
// arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
|
// arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
|
||||||
|
// s390x:"SUBC"
|
||||||
return bits.Sub(x, y, 0)
|
return bits.Sub(x, y, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SubR(x, y, ci uint) uint {
|
func SubR(x, y, ci uint) uint {
|
||||||
// amd64:"NEGL","SBBQ",-"NEGQ"
|
// amd64:"NEGL","SBBQ",-"NEGQ"
|
||||||
// arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
|
// arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
r, _ := bits.Sub(x, y, ci)
|
r, _ := bits.Sub(x, y, ci)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
@ -483,6 +498,7 @@ func SubM(p, q, r *[3]uint) {
|
||||||
r[0], c = bits.Sub(p[0], q[0], c)
|
r[0], c = bits.Sub(p[0], q[0], c)
|
||||||
// amd64:"SBBQ",-"NEGL",-"NEGQ"
|
// amd64:"SBBQ",-"NEGL",-"NEGQ"
|
||||||
// arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
|
// arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
r[1], c = bits.Sub(p[1], q[1], c)
|
r[1], c = bits.Sub(p[1], q[1], c)
|
||||||
r[2], c = bits.Sub(p[2], q[2], c)
|
r[2], c = bits.Sub(p[2], q[2], c)
|
||||||
}
|
}
|
||||||
|
|
@ -490,24 +506,28 @@ func SubM(p, q, r *[3]uint) {
|
||||||
func Sub64(x, y, ci uint64) (r, co uint64) {
|
func Sub64(x, y, ci uint64) (r, co uint64) {
|
||||||
// amd64:"NEGL","SBBQ","NEGQ"
|
// amd64:"NEGL","SBBQ","NEGQ"
|
||||||
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
return bits.Sub64(x, y, ci)
|
return bits.Sub64(x, y, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sub64C(x, ci uint64) (r, co uint64) {
|
func Sub64C(x, ci uint64) (r, co uint64) {
|
||||||
// amd64:"NEGL","SBBQ","NEGQ"
|
// amd64:"NEGL","SBBQ","NEGQ"
|
||||||
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
return bits.Sub64(x, 7, ci)
|
return bits.Sub64(x, 7, ci)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sub64Z(x, y uint64) (r, co uint64) {
|
func Sub64Z(x, y uint64) (r, co uint64) {
|
||||||
// amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
|
// amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
|
||||||
// arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
|
// arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
|
||||||
|
// s390x:"SUBC"
|
||||||
return bits.Sub64(x, y, 0)
|
return bits.Sub64(x, y, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sub64R(x, y, ci uint64) uint64 {
|
func Sub64R(x, y, ci uint64) uint64 {
|
||||||
// amd64:"NEGL","SBBQ",-"NEGQ"
|
// amd64:"NEGL","SBBQ",-"NEGQ"
|
||||||
// arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
|
// arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
r, _ := bits.Sub64(x, y, ci)
|
r, _ := bits.Sub64(x, y, ci)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
@ -516,6 +536,7 @@ func Sub64M(p, q, r *[3]uint64) {
|
||||||
r[0], c = bits.Sub64(p[0], q[0], c)
|
r[0], c = bits.Sub64(p[0], q[0], c)
|
||||||
// amd64:"SBBQ",-"NEGL",-"NEGQ"
|
// amd64:"SBBQ",-"NEGL",-"NEGQ"
|
||||||
// arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
|
// arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
|
||||||
|
// s390x:"SUBE"
|
||||||
r[1], c = bits.Sub64(p[1], q[1], c)
|
r[1], c = bits.Sub64(p[1], q[1], c)
|
||||||
r[2], c = bits.Sub64(p[2], q[2], c)
|
r[2], c = bits.Sub64(p[2], q[2], c)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue