cmd/compile: automate resultInArg0 register checks

No functional changes; passes toolstash-check.
No measureable performance changes.

Change-Id: I2629f73d4a3cc56d80f512f33cf57cf41d8f15d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/296010
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2021-01-07 19:08:37 -08:00
parent 1a3e968b1f
commit 4ebb6f5110
12 changed files with 52 additions and 166 deletions

View file

@ -202,9 +202,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[2].Reg()} p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[2].Reg()}
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()} p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()}) p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()})
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL: case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL:
r := v.Reg() r := v.Reg()
r1 := v.Args[0].Reg() r1 := v.Args[0].Reg()
@ -254,11 +251,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.OpAMD64BTSL, ssa.OpAMD64BTSQ, ssa.OpAMD64BTSL, ssa.OpAMD64BTSQ,
ssa.OpAMD64BTCL, ssa.OpAMD64BTCQ, ssa.OpAMD64BTCL, ssa.OpAMD64BTCQ,
ssa.OpAMD64BTRL, ssa.OpAMD64BTRQ: ssa.OpAMD64BTRL, ssa.OpAMD64BTRQ:
r := v.Reg() opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
case ssa.OpAMD64DIVQU, ssa.OpAMD64DIVLU, ssa.OpAMD64DIVWU: case ssa.OpAMD64DIVQU, ssa.OpAMD64DIVLU, ssa.OpAMD64DIVWU:
// Arg[0] (the dividend) is in AX. // Arg[0] (the dividend) is in AX.
@ -401,20 +394,16 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
// compute (x+y)/2 unsigned. // compute (x+y)/2 unsigned.
// Do a 64-bit add, the overflow goes into the carry. // Do a 64-bit add, the overflow goes into the carry.
// Shift right once and pull the carry back into the 63rd bit. // Shift right once and pull the carry back into the 63rd bit.
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(x86.AADDQ) p := s.Prog(x86.AADDQ)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
p.From.Reg = v.Args[1].Reg() p.From.Reg = v.Args[1].Reg()
p = s.Prog(x86.ARCRQ) p = s.Prog(x86.ARCRQ)
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 1 p.From.Offset = 1
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpAMD64ADDQcarry, ssa.OpAMD64ADCQ: case ssa.OpAMD64ADDQcarry, ssa.OpAMD64ADCQ:
r := v.Reg0() r := v.Reg0()
@ -530,21 +519,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.OpAMD64CMOVQCS, ssa.OpAMD64CMOVLCS, ssa.OpAMD64CMOVWCS, ssa.OpAMD64CMOVQCS, ssa.OpAMD64CMOVLCS, ssa.OpAMD64CMOVWCS,
ssa.OpAMD64CMOVQGTF, ssa.OpAMD64CMOVLGTF, ssa.OpAMD64CMOVWGTF, ssa.OpAMD64CMOVQGTF, ssa.OpAMD64CMOVLGTF, ssa.OpAMD64CMOVWGTF,
ssa.OpAMD64CMOVQGEF, ssa.OpAMD64CMOVLGEF, ssa.OpAMD64CMOVWGEF: ssa.OpAMD64CMOVQGEF, ssa.OpAMD64CMOVLGEF, ssa.OpAMD64CMOVWGEF:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[1].Reg() p.From.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpAMD64CMOVQNEF, ssa.OpAMD64CMOVLNEF, ssa.OpAMD64CMOVWNEF: case ssa.OpAMD64CMOVQNEF, ssa.OpAMD64CMOVLNEF, ssa.OpAMD64CMOVWNEF:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
// Flag condition: ^ZERO || PARITY // Flag condition: ^ZERO || PARITY
// Generate: // Generate:
// CMOV*NE SRC,DST // CMOV*NE SRC,DST
@ -553,7 +534,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[1].Reg() p.From.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
var q *obj.Prog var q *obj.Prog
if v.Op == ssa.OpAMD64CMOVQNEF { if v.Op == ssa.OpAMD64CMOVQNEF {
q = s.Prog(x86.ACMOVQPS) q = s.Prog(x86.ACMOVQPS)
@ -565,14 +546,9 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = v.Args[1].Reg() q.From.Reg = v.Args[1].Reg()
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = r q.To.Reg = v.Reg()
case ssa.OpAMD64CMOVQEQF, ssa.OpAMD64CMOVLEQF, ssa.OpAMD64CMOVWEQF: case ssa.OpAMD64CMOVQEQF, ssa.OpAMD64CMOVLEQF, ssa.OpAMD64CMOVWEQF:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
// Flag condition: ZERO && !PARITY // Flag condition: ZERO && !PARITY
// Generate: // Generate:
// MOV SRC,AX // MOV SRC,AX
@ -589,7 +565,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
} }
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = r p.From.Reg = v.Reg()
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_AX p.To.Reg = x86.REG_AX
var q *obj.Prog var q *obj.Prog
@ -603,7 +579,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = x86.REG_AX q.From.Reg = x86.REG_AX
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = r q.To.Reg = v.Reg()
case ssa.OpAMD64MULQconst, ssa.OpAMD64MULLconst: case ssa.OpAMD64MULQconst, ssa.OpAMD64MULLconst:
r := v.Reg() r := v.Reg()
@ -622,15 +598,11 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.OpAMD64SHRQconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SHRWconst, ssa.OpAMD64SHRBconst, ssa.OpAMD64SHRQconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SHRWconst, ssa.OpAMD64SHRBconst,
ssa.OpAMD64SARQconst, ssa.OpAMD64SARLconst, ssa.OpAMD64SARWconst, ssa.OpAMD64SARBconst, ssa.OpAMD64SARQconst, ssa.OpAMD64SARLconst, ssa.OpAMD64SARWconst, ssa.OpAMD64SARBconst,
ssa.OpAMD64ROLQconst, ssa.OpAMD64ROLLconst, ssa.OpAMD64ROLWconst, ssa.OpAMD64ROLBconst: ssa.OpAMD64ROLQconst, ssa.OpAMD64ROLLconst, ssa.OpAMD64ROLWconst, ssa.OpAMD64ROLBconst:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpAMD64SBBQcarrymask, ssa.OpAMD64SBBLcarrymask: case ssa.OpAMD64SBBQcarrymask, ssa.OpAMD64SBBLcarrymask:
r := v.Reg() r := v.Reg()
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
@ -913,9 +885,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssagen.AddAux(&p.From, v) ssagen.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
case ssa.OpAMD64ADDLloadidx1, ssa.OpAMD64ADDLloadidx4, ssa.OpAMD64ADDLloadidx8, ssa.OpAMD64ADDQloadidx1, ssa.OpAMD64ADDQloadidx8, case ssa.OpAMD64ADDLloadidx1, ssa.OpAMD64ADDLloadidx4, ssa.OpAMD64ADDLloadidx8, ssa.OpAMD64ADDQloadidx1, ssa.OpAMD64ADDQloadidx8,
ssa.OpAMD64SUBLloadidx1, ssa.OpAMD64SUBLloadidx4, ssa.OpAMD64SUBLloadidx8, ssa.OpAMD64SUBQloadidx1, ssa.OpAMD64SUBQloadidx8, ssa.OpAMD64SUBLloadidx1, ssa.OpAMD64SUBLloadidx4, ssa.OpAMD64SUBLloadidx8, ssa.OpAMD64SUBQloadidx1, ssa.OpAMD64SUBQloadidx8,
ssa.OpAMD64ANDLloadidx1, ssa.OpAMD64ANDLloadidx4, ssa.OpAMD64ANDLloadidx8, ssa.OpAMD64ANDQloadidx1, ssa.OpAMD64ANDQloadidx8, ssa.OpAMD64ANDLloadidx1, ssa.OpAMD64ANDLloadidx4, ssa.OpAMD64ANDLloadidx8, ssa.OpAMD64ANDQloadidx1, ssa.OpAMD64ANDQloadidx8,
@ -939,9 +908,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssagen.AddAux(&p.From, v) ssagen.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
case ssa.OpAMD64DUFFZERO: case ssa.OpAMD64DUFFZERO:
if s.ABI != obj.ABIInternal { if s.ABI != obj.ABIInternal {
v.Fatalf("MOVOconst can be only used in ABIInternal functions") v.Fatalf("MOVOconst can be only used in ABIInternal functions")
@ -1078,22 +1044,14 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL, case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL, ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL: ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpAMD64NEGLflags: case ssa.OpAMD64NEGLflags:
r := v.Reg0()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg0()
case ssa.OpAMD64BSFQ, ssa.OpAMD64BSRQ, ssa.OpAMD64BSFL, ssa.OpAMD64BSRL, ssa.OpAMD64SQRTSD: case ssa.OpAMD64BSFQ, ssa.OpAMD64BSRQ, ssa.OpAMD64BSFL, ssa.OpAMD64BSRL, ssa.OpAMD64SQRTSD:
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
@ -1214,25 +1172,17 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg0() p.To.Reg = v.Reg0()
case ssa.OpAMD64XCHGB, ssa.OpAMD64XCHGL, ssa.OpAMD64XCHGQ: case ssa.OpAMD64XCHGB, ssa.OpAMD64XCHGL, ssa.OpAMD64XCHGQ:
r := v.Reg0()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = r p.From.Reg = v.Reg0()
p.To.Type = obj.TYPE_MEM p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[1].Reg() p.To.Reg = v.Args[1].Reg()
ssagen.AddAux(&p.To, v) ssagen.AddAux(&p.To, v)
case ssa.OpAMD64XADDLlock, ssa.OpAMD64XADDQlock: case ssa.OpAMD64XADDLlock, ssa.OpAMD64XADDQlock:
r := v.Reg0()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
}
s.Prog(x86.ALOCK) s.Prog(x86.ALOCK)
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = r p.From.Reg = v.Reg0()
p.To.Type = obj.TYPE_MEM p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[1].Reg() p.To.Reg = v.Args[1].Reg()
ssagen.AddAux(&p.To, v) ssagen.AddAux(&p.To, v)

View file

@ -173,9 +173,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = y p.To.Reg = y
case ssa.OpARMMOVWnop: case ssa.OpARMMOVWnop:
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
// nothing to do // nothing to do
case ssa.OpLoadReg: case ssa.OpLoadReg:
if v.Type.IsFlags() { if v.Type.IsFlags() {

View file

@ -142,9 +142,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = y p.To.Reg = y
case ssa.OpARM64MOVDnop: case ssa.OpARM64MOVDnop:
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
// nothing to do // nothing to do
case ssa.OpLoadReg: case ssa.OpLoadReg:
if v.Type.IsFlags() { if v.Type.IsFlags() {
@ -522,17 +519,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssagen.AddAux(&p.To, v) ssagen.AddAux(&p.To, v)
case ssa.OpARM64BFI, case ssa.OpARM64BFI,
ssa.OpARM64BFXIL: ssa.OpARM64BFXIL:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt >> 8 p.From.Offset = v.AuxInt >> 8
p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: v.AuxInt & 0xff}) p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: v.AuxInt & 0xff})
p.Reg = v.Args[1].Reg() p.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpARM64SBFIZ, case ssa.OpARM64SBFIZ,
ssa.OpARM64SBFX, ssa.OpARM64SBFX,
ssa.OpARM64UBFIZ, ssa.OpARM64UBFIZ,

View file

@ -112,9 +112,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Reg = y p.To.Reg = y
} }
case ssa.OpMIPSMOVWnop: case ssa.OpMIPSMOVWnop:
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
// nothing to do // nothing to do
case ssa.OpLoadReg: case ssa.OpLoadReg:
if v.Type.IsFlags() { if v.Type.IsFlags() {
@ -244,9 +241,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
case ssa.OpMIPSCMOVZ: case ssa.OpMIPSCMOVZ:
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[2].Reg() p.From.Reg = v.Args[2].Reg()
@ -254,9 +248,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
case ssa.OpMIPSCMOVZzero: case ssa.OpMIPSCMOVZzero:
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[1].Reg() p.From.Reg = v.Args[1].Reg()

View file

@ -115,9 +115,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Reg = y p.To.Reg = y
} }
case ssa.OpMIPS64MOVVnop: case ssa.OpMIPS64MOVVnop:
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
// nothing to do // nothing to do
case ssa.OpLoadReg: case ssa.OpLoadReg:
if v.Type.IsFlags() { if v.Type.IsFlags() {

View file

@ -211,9 +211,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = rd p.To.Reg = rd
case ssa.OpRISCV64MOVDnop: case ssa.OpRISCV64MOVDnop:
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
// nothing to do // nothing to do
case ssa.OpLoadReg: case ssa.OpLoadReg:
if v.Type.IsFlags() { if v.Type.IsFlags() {

View file

@ -175,10 +175,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.Reg = r1 p.Reg = r1
} }
case ssa.OpS390XRXSBG: case ssa.OpS390XRXSBG:
r1 := v.Reg()
if r1 != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
r2 := v.Args[1].Reg() r2 := v.Args[1].Reg()
i := v.Aux.(s390x.RotateParams) i := v.Aux.(s390x.RotateParams)
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
@ -188,7 +184,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
{Type: obj.TYPE_CONST, Offset: int64(i.Amount)}, {Type: obj.TYPE_CONST, Offset: int64(i.Amount)},
{Type: obj.TYPE_REG, Reg: r2}, {Type: obj.TYPE_REG, Reg: r2},
}) })
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: r1} p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
case ssa.OpS390XRISBGZ: case ssa.OpS390XRISBGZ:
r1 := v.Reg() r1 := v.Reg()
r2 := v.Args[0].Reg() r2 := v.Args[0].Reg()
@ -233,12 +229,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.Reg = r2 p.Reg = r2
} }
case ssa.OpS390XADDE, ssa.OpS390XSUBE: 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() r2 := v.Args[1].Reg()
opregreg(s, v.Op.Asm(), r1, r2) opregreg(s, v.Op.Asm(), v.Reg0(), r2)
case ssa.OpS390XADDCconst: case ssa.OpS390XADDCconst:
r1 := v.Reg0() r1 := v.Reg0()
r3 := v.Args[0].Reg() r3 := v.Args[0].Reg()
@ -248,18 +240,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
case ssa.OpS390XMULLD, ssa.OpS390XMULLW, case ssa.OpS390XMULLD, ssa.OpS390XMULLW,
ssa.OpS390XMULHD, ssa.OpS390XMULHDU, ssa.OpS390XMULHD, ssa.OpS390XMULHDU,
ssa.OpS390XFMULS, ssa.OpS390XFMUL, ssa.OpS390XFDIVS, ssa.OpS390XFDIV: ssa.OpS390XFMULS, ssa.OpS390XFMUL, ssa.OpS390XFDIVS, ssa.OpS390XFDIV:
r := v.Reg() opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
case ssa.OpS390XFSUBS, ssa.OpS390XFSUB, case ssa.OpS390XFSUBS, ssa.OpS390XFSUB,
ssa.OpS390XFADDS, ssa.OpS390XFADD: ssa.OpS390XFADDS, ssa.OpS390XFADD:
r := v.Reg0() opregreg(s, v.Op.Asm(), v.Reg0(), v.Args[1].Reg())
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
case ssa.OpS390XMLGR: case ssa.OpS390XMLGR:
// MLGR Rx R3 -> R2:R3 // MLGR Rx R3 -> R2:R3
r0 := v.Args[0].Reg() r0 := v.Args[0].Reg()
@ -274,10 +258,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
case ssa.OpS390XFMADD, ssa.OpS390XFMADDS, case ssa.OpS390XFMADD, ssa.OpS390XFMADDS,
ssa.OpS390XFMSUB, ssa.OpS390XFMSUBS: ssa.OpS390XFMSUB, ssa.OpS390XFMSUBS:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
r1 := v.Args[1].Reg() r1 := v.Args[1].Reg()
r2 := v.Args[2].Reg() r2 := v.Args[2].Reg()
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
@ -285,7 +265,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.From.Reg = r1 p.From.Reg = r1
p.Reg = r2 p.Reg = r2
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpS390XFIDBR: case ssa.OpS390XFIDBR:
switch v.AuxInt { switch v.AuxInt {
case 0, 1, 3, 4, 5, 6, 7: case 0, 1, 3, 4, 5, 6, 7:
@ -361,15 +341,11 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.OpS390XANDconst, ssa.OpS390XANDWconst, ssa.OpS390XANDconst, ssa.OpS390XANDWconst,
ssa.OpS390XORconst, ssa.OpS390XORWconst, ssa.OpS390XORconst, ssa.OpS390XORWconst,
ssa.OpS390XXORconst, ssa.OpS390XXORWconst: ssa.OpS390XXORconst, ssa.OpS390XXORWconst:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpS390XSLDconst, ssa.OpS390XSLWconst, case ssa.OpS390XSLDconst, ssa.OpS390XSLWconst,
ssa.OpS390XSRDconst, ssa.OpS390XSRWconst, ssa.OpS390XSRDconst, ssa.OpS390XSRWconst,
ssa.OpS390XSRADconst, ssa.OpS390XSRAWconst, ssa.OpS390XSRADconst, ssa.OpS390XSRAWconst,
@ -441,16 +417,12 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.OpS390XANDWload, ssa.OpS390XANDload, ssa.OpS390XANDWload, ssa.OpS390XANDload,
ssa.OpS390XORWload, ssa.OpS390XORload, ssa.OpS390XORWload, ssa.OpS390XORload,
ssa.OpS390XXORWload, ssa.OpS390XXORload: ssa.OpS390XXORWload, ssa.OpS390XXORload:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Reg = v.Args[1].Reg() p.From.Reg = v.Args[1].Reg()
ssagen.AddAux(&p.From, v) ssagen.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpS390XMOVDload, case ssa.OpS390XMOVDload,
ssa.OpS390XMOVWZload, ssa.OpS390XMOVHZload, ssa.OpS390XMOVBZload, ssa.OpS390XMOVWZload, ssa.OpS390XMOVHZload, ssa.OpS390XMOVBZload,
ssa.OpS390XMOVDBRload, ssa.OpS390XMOVWBRload, ssa.OpS390XMOVHBRload, ssa.OpS390XMOVDBRload, ssa.OpS390XMOVWBRload, ssa.OpS390XMOVHBRload,
@ -608,16 +580,12 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
case ssa.OpS390XSumBytes2, ssa.OpS390XSumBytes4, ssa.OpS390XSumBytes8: case ssa.OpS390XSumBytes2, ssa.OpS390XSumBytes4, ssa.OpS390XSumBytes8:
v.Fatalf("SumBytes generated %s", v.LongString()) v.Fatalf("SumBytes generated %s", v.LongString())
case ssa.OpS390XLOCGR: case ssa.OpS390XLOCGR:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(v.Aux.(s390x.CCMask)) p.From.Offset = int64(v.Aux.(s390x.CCMask))
p.Reg = v.Args[1].Reg() p.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.OpS390XFSQRT: case ssa.OpS390XFSQRT:
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG

View file

@ -407,6 +407,7 @@ func genOp() {
fmt.Fprintln(w, "func (o Op) IsCall() bool { return opcodeTable[o].call }") fmt.Fprintln(w, "func (o Op) IsCall() bool { return opcodeTable[o].call }")
fmt.Fprintln(w, "func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects }") fmt.Fprintln(w, "func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects }")
fmt.Fprintln(w, "func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }") fmt.Fprintln(w, "func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }")
fmt.Fprintln(w, "func (o Op) ResultInArg0() bool { return opcodeTable[o].resultInArg0 }")
// generate registers // generate registers
for _, a := range archs { for _, a := range archs {

View file

@ -36193,6 +36193,7 @@ func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }
func (o Op) IsCall() bool { return opcodeTable[o].call } func (o Op) IsCall() bool { return opcodeTable[o].call }
func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects } func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects }
func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint } func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }
func (o Op) ResultInArg0() bool { return opcodeTable[o].resultInArg0 }
var registers386 = [...]Register{ var registers386 = [...]Register{
{0, x86.REG_AX, 0, "AX"}, {0, x86.REG_AX, 0, "AX"},

View file

@ -411,6 +411,23 @@ func (v *Value) isGenericIntConst() bool {
return v != nil && (v.Op == OpConst64 || v.Op == OpConst32 || v.Op == OpConst16 || v.Op == OpConst8) return v != nil && (v.Op == OpConst64 || v.Op == OpConst32 || v.Op == OpConst16 || v.Op == OpConst8)
} }
// ResultReg returns the result register assigned to v, in cmd/internal/obj/$ARCH numbering.
// It is similar to Reg and Reg0, except that it is usable interchangeably for all Value Ops.
// If you know v.Op, using Reg or Reg0 (as appropriate) will be more efficient.
func (v *Value) ResultReg() int16 {
reg := v.Block.Func.RegAlloc[v.ID]
if reg == nil {
v.Fatalf("nil reg for value: %s\n%s\n", v.LongString(), v.Block.Func)
}
if pair, ok := reg.(LocPair); ok {
reg = pair[0]
}
if reg == nil {
v.Fatalf("nil reg0 for value: %s\n%s\n", v.LongString(), v.Block.Func)
}
return reg.(*Register).objNum
}
// Reg returns the register assigned to v, in cmd/internal/obj/$ARCH numbering. // Reg returns the register assigned to v, in cmd/internal/obj/$ARCH numbering.
func (v *Value) Reg() int16 { func (v *Value) Reg() int16 {
reg := v.Block.Func.RegAlloc[v.ID] reg := v.Block.Func.RegAlloc[v.ID]

View file

@ -6509,6 +6509,10 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
x := s.pp.Next x := s.pp.Next
s.DebugFriendlySetPosFrom(v) s.DebugFriendlySetPosFrom(v)
if v.Op.ResultInArg0() && v.ResultReg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
switch v.Op { switch v.Op {
case ssa.OpInitMem: case ssa.OpInitMem:
// memory arg needs no code // memory arg needs no code

View file

@ -161,31 +161,19 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.Op386PXOR, ssa.Op386PXOR,
ssa.Op386ADCL, ssa.Op386ADCL,
ssa.Op386SBBL: ssa.Op386SBBL:
r := v.Reg() opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
case ssa.Op386ADDLcarry, ssa.Op386SUBLcarry: case ssa.Op386ADDLcarry, ssa.Op386SUBLcarry:
// output 0 is carry/borrow, output 1 is the low 32 bits. // output 0 is carry/borrow, output 1 is the low 32 bits.
r := v.Reg0() opregreg(s, v.Op.Asm(), v.Reg0(), v.Args[1].Reg())
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
}
opregreg(s, v.Op.Asm(), r, v.Args[1].Reg())
case ssa.Op386ADDLconstcarry, ssa.Op386SUBLconstcarry: case ssa.Op386ADDLconstcarry, ssa.Op386SUBLconstcarry:
// output 0 is carry/borrow, output 1 is the low 32 bits. // output 0 is carry/borrow, output 1 is the low 32 bits.
r := v.Reg0()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg0()
case ssa.Op386DIVL, ssa.Op386DIVW, case ssa.Op386DIVL, ssa.Op386DIVW,
ssa.Op386DIVLU, ssa.Op386DIVWU, ssa.Op386DIVLU, ssa.Op386DIVWU,
@ -306,20 +294,16 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
// compute (x+y)/2 unsigned. // compute (x+y)/2 unsigned.
// Do a 32-bit add, the overflow goes into the carry. // Do a 32-bit add, the overflow goes into the carry.
// Shift right once and pull the carry back into the 31st bit. // Shift right once and pull the carry back into the 31st bit.
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(x86.AADDL) p := s.Prog(x86.AADDL)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
p.From.Reg = v.Args[1].Reg() p.From.Reg = v.Args[1].Reg()
p = s.Prog(x86.ARCRL) p = s.Prog(x86.ARCRL)
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 1 p.From.Offset = 1
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.Op386ADDLconst: case ssa.Op386ADDLconst:
r := v.Reg() r := v.Reg()
@ -370,15 +354,11 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.Op386SHRLconst, ssa.Op386SHRWconst, ssa.Op386SHRBconst, ssa.Op386SHRLconst, ssa.Op386SHRWconst, ssa.Op386SHRBconst,
ssa.Op386SARLconst, ssa.Op386SARWconst, ssa.Op386SARBconst, ssa.Op386SARLconst, ssa.Op386SARWconst, ssa.Op386SARBconst,
ssa.Op386ROLLconst, ssa.Op386ROLWconst, ssa.Op386ROLBconst: ssa.Op386ROLLconst, ssa.Op386ROLWconst, ssa.Op386ROLBconst:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.Op386SBBLcarrymask: case ssa.Op386SBBLcarrymask:
r := v.Reg() r := v.Reg()
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
@ -536,9 +516,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssagen.AddAux(&p.From, v) ssagen.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
case ssa.Op386ADDLload, ssa.Op386SUBLload, ssa.Op386MULLload, case ssa.Op386ADDLload, ssa.Op386SUBLload, ssa.Op386MULLload,
ssa.Op386ANDLload, ssa.Op386ORLload, ssa.Op386XORLload, ssa.Op386ANDLload, ssa.Op386ORLload, ssa.Op386XORLload,
ssa.Op386ADDSDload, ssa.Op386ADDSSload, ssa.Op386SUBSDload, ssa.Op386SUBSSload, ssa.Op386ADDSDload, ssa.Op386ADDSSload, ssa.Op386SUBSDload, ssa.Op386SUBSSload,
@ -549,9 +526,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssagen.AddAux(&p.From, v) ssagen.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
if v.Reg() != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
case ssa.Op386MOVSSstore, ssa.Op386MOVSDstore, ssa.Op386MOVLstore, ssa.Op386MOVWstore, ssa.Op386MOVBstore, case ssa.Op386MOVSSstore, ssa.Op386MOVSDstore, ssa.Op386MOVLstore, ssa.Op386MOVWstore, ssa.Op386MOVBstore,
ssa.Op386ADDLmodify, ssa.Op386SUBLmodify, ssa.Op386ANDLmodify, ssa.Op386ORLmodify, ssa.Op386XORLmodify: ssa.Op386ADDLmodify, ssa.Op386SUBLmodify, ssa.Op386ANDLmodify, ssa.Op386ORLmodify, ssa.Op386XORLmodify:
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
@ -781,13 +755,9 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
case ssa.Op386NEGL, case ssa.Op386NEGL,
ssa.Op386BSWAPL, ssa.Op386BSWAPL,
ssa.Op386NOTL: ssa.Op386NOTL:
r := v.Reg()
if r != v.Args[0].Reg() {
v.Fatalf("input[0] and output not in same register %s", v.LongString())
}
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = v.Reg()
case ssa.Op386BSFL, ssa.Op386BSFW, case ssa.Op386BSFL, ssa.Op386BSFW,
ssa.Op386BSRL, ssa.Op386BSRW, ssa.Op386BSRL, ssa.Op386BSRW,
ssa.Op386SQRTSD: ssa.Op386SQRTSD: