mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/asm: refine some APIs related to Prog.RestArgs[]
Before this CL, we use GetFrom3&SetFrom3 to get or set a source operand which not fit into Prog.Reg. Those APIs operate the first element in Prog.RestArgs without checking the type so they're fragile to break if we have more than one different type of operands in the slice, which will be a common case in Arm64. This CL deprecates & renames some APIs related to Prog.RestArgs to make those APIs more reasonable and robust than before. Change-Id: I70d56edc1f23ccfffbcd6df34844e2cef2288432 Reviewed-on: https://go-review.googlesource.com/c/go/+/493355 Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Eric Fang <eric.fang@arm.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Eric Fang <eric.fang@arm.com>
This commit is contained in:
parent
bdc5533f39
commit
cf624a6127
12 changed files with 99 additions and 105 deletions
|
|
@ -485,7 +485,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
} else {
|
} else {
|
||||||
// Compare register with immediate and jump.
|
// Compare register with immediate and jump.
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -508,7 +508,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
|
||||||
// 4-operand compare-and-branch.
|
// 4-operand compare-and-branch.
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.SetFrom3(a[2])
|
prog.AddRestSource(a[2])
|
||||||
target = &a[3]
|
target = &a[3]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -682,7 +682,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
if arch.IsARMBFX(op) {
|
if arch.IsARMBFX(op) {
|
||||||
// a[0] and a[1] must be constants, a[2] must be a register
|
// a[0] and a[1] must be constants, a[2] must be a register
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -692,7 +692,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
case sys.AMD64:
|
case sys.AMD64:
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
case sys.ARM64:
|
case sys.ARM64:
|
||||||
switch {
|
switch {
|
||||||
|
|
@ -708,7 +708,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
case arch.IsARM64TBL(op):
|
case arch.IsARM64TBL(op):
|
||||||
// one of its inputs does not fit into prog.Reg.
|
// one of its inputs does not fit into prog.Reg.
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
case arch.IsARM64CASP(op):
|
case arch.IsARM64CASP(op):
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
|
|
@ -721,7 +721,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
}
|
}
|
||||||
// For ARM64 CASP-like instructions, its 2nd destination operand is register pair(Rt, Rt+1) that can
|
// For ARM64 CASP-like instructions, its 2nd destination operand is register pair(Rt, Rt+1) that can
|
||||||
// not fit into prog.RegTo2, so save it to the prog.RestArgs.
|
// not fit into prog.RegTo2, so save it to the prog.RestArgs.
|
||||||
prog.SetTo2(a[2])
|
prog.AddRestDest(a[2])
|
||||||
default:
|
default:
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
|
|
@ -729,7 +729,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
}
|
}
|
||||||
case sys.I386:
|
case sys.I386:
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
case sys.PPC64:
|
case sys.PPC64:
|
||||||
if arch.IsPPC64CMP(op) {
|
if arch.IsPPC64CMP(op) {
|
||||||
|
|
@ -744,12 +744,12 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
|
|
||||||
// If the second argument is not a register argument, it must be
|
// If the second argument is not a register argument, it must be
|
||||||
// passed RestArgs/SetFrom3
|
// passed RestArgs/AddRestSource
|
||||||
switch a[1].Type {
|
switch a[1].Type {
|
||||||
case obj.TYPE_REG:
|
case obj.TYPE_REG:
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
default:
|
default:
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
}
|
}
|
||||||
case sys.RISCV64:
|
case sys.RISCV64:
|
||||||
// RISCV64 instructions with one input and two outputs.
|
// RISCV64 instructions with one input and two outputs.
|
||||||
|
|
@ -771,7 +771,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
if a[1].Type == obj.TYPE_REG {
|
if a[1].Type == obj.TYPE_REG {
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
} else {
|
} else {
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
}
|
}
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
default:
|
default:
|
||||||
|
|
@ -783,7 +783,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
if arch.IsARMBFX(op) {
|
if arch.IsARMBFX(op) {
|
||||||
// a[0] and a[1] must be constants, a[2] and a[3] must be registers
|
// a[0] and a[1] must be constants, a[2] and a[3] must be registers
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetFrom3(a[1])
|
prog.AddRestSource(a[1])
|
||||||
prog.Reg = p.getRegister(prog, op, &a[2])
|
prog.Reg = p.getRegister(prog, op, &a[2])
|
||||||
prog.To = a[3]
|
prog.To = a[3]
|
||||||
break
|
break
|
||||||
|
|
@ -804,14 +804,14 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
}
|
}
|
||||||
if p.arch.Family == sys.AMD64 {
|
if p.arch.Family == sys.AMD64 {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetRestArgs([]obj.Addr{a[1], a[2]})
|
prog.AddRestSourceArgs([]obj.Addr{a[1], a[2]})
|
||||||
prog.To = a[3]
|
prog.To = a[3]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.arch.Family == sys.ARM64 {
|
if p.arch.Family == sys.ARM64 {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.SetFrom3(a[2])
|
prog.AddRestSource(a[2])
|
||||||
prog.To = a[3]
|
prog.To = a[3]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -819,20 +819,20 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.To = a[3]
|
prog.To = a[3]
|
||||||
// If the second argument is not a register argument, it must be
|
// If the second argument is not a register argument, it must be
|
||||||
// passed RestArgs/SetFrom3
|
// passed RestArgs/AddRestSource
|
||||||
if a[1].Type == obj.TYPE_REG {
|
if a[1].Type == obj.TYPE_REG {
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.SetRestArgs([]obj.Addr{a[2]})
|
prog.AddRestSource(a[2])
|
||||||
} else {
|
} else {
|
||||||
// Don't set prog.Reg if a1 isn't a reg arg.
|
// Don't set prog.Reg if a1 isn't a reg arg.
|
||||||
prog.SetRestArgs([]obj.Addr{a[1], a[2]})
|
prog.AddRestSourceArgs([]obj.Addr{a[1], a[2]})
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.arch.Family == sys.RISCV64 {
|
if p.arch.Family == sys.RISCV64 {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.SetRestArgs([]obj.Addr{a[2]})
|
prog.AddRestSource(a[2])
|
||||||
prog.To = a[3]
|
prog.To = a[3]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -843,7 +843,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
}
|
}
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.SetFrom3(a[2])
|
prog.AddRestSource(a[2])
|
||||||
prog.To = a[3]
|
prog.To = a[3]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -854,19 +854,19 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
// Second arg is always a register type on ppc64.
|
// Second arg is always a register type on ppc64.
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.SetRestArgs([]obj.Addr{a[2], a[3]})
|
prog.AddRestSourceArgs([]obj.Addr{a[2], a[3]})
|
||||||
prog.To = a[4]
|
prog.To = a[4]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.arch.Family == sys.AMD64 {
|
if p.arch.Family == sys.AMD64 {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetRestArgs([]obj.Addr{a[1], a[2], a[3]})
|
prog.AddRestSourceArgs([]obj.Addr{a[1], a[2], a[3]})
|
||||||
prog.To = a[4]
|
prog.To = a[4]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.arch.Family == sys.S390X {
|
if p.arch.Family == sys.S390X {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.SetRestArgs([]obj.Addr{a[1], a[2], a[3]})
|
prog.AddRestSourceArgs([]obj.Addr{a[1], a[2], a[3]})
|
||||||
prog.To = a[4]
|
prog.To = a[4]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -896,7 +896,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
// Second arg is always a register type on ppc64.
|
// Second arg is always a register type on ppc64.
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.SetRestArgs([]obj.Addr{a[2], a[3], a[4]})
|
prog.AddRestSourceArgs([]obj.Addr{a[2], a[3], a[4]})
|
||||||
prog.To = a[5]
|
prog.To = a[5]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
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.SetFrom3Reg(v.Args[1].Reg())
|
p.AddRestSourceReg(v.Args[1].Reg())
|
||||||
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()
|
||||||
|
|
@ -265,7 +265,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.From.Reg = bits
|
p.From.Reg = bits
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = lo
|
p.To.Reg = lo
|
||||||
p.SetFrom3Reg(hi)
|
p.AddRestSourceReg(hi)
|
||||||
|
|
||||||
case ssa.OpAMD64BLSIQ, ssa.OpAMD64BLSIL,
|
case ssa.OpAMD64BLSIQ, ssa.OpAMD64BLSIL,
|
||||||
ssa.OpAMD64BLSMSKQ, ssa.OpAMD64BLSMSKL,
|
ssa.OpAMD64BLSMSKQ, ssa.OpAMD64BLSMSKL,
|
||||||
|
|
@ -287,13 +287,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.From.Reg = v.Args[0].Reg()
|
p.From.Reg = v.Args[0].Reg()
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
p.SetFrom3Reg(v.Args[1].Reg())
|
p.AddRestSourceReg(v.Args[1].Reg())
|
||||||
|
|
||||||
case ssa.OpAMD64SARXL, ssa.OpAMD64SARXQ,
|
case ssa.OpAMD64SARXL, ssa.OpAMD64SARXQ,
|
||||||
ssa.OpAMD64SHLXL, ssa.OpAMD64SHLXQ,
|
ssa.OpAMD64SHLXL, ssa.OpAMD64SHLXQ,
|
||||||
ssa.OpAMD64SHRXL, ssa.OpAMD64SHRXQ:
|
ssa.OpAMD64SHRXL, ssa.OpAMD64SHRXQ:
|
||||||
p := opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
|
p := opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
|
||||||
p.SetFrom3Reg(v.Args[0].Reg())
|
p.AddRestSourceReg(v.Args[0].Reg())
|
||||||
|
|
||||||
case ssa.OpAMD64SHLXLload, ssa.OpAMD64SHLXQload,
|
case ssa.OpAMD64SHLXLload, ssa.OpAMD64SHLXQload,
|
||||||
ssa.OpAMD64SHRXLload, ssa.OpAMD64SHRXQload,
|
ssa.OpAMD64SHRXLload, ssa.OpAMD64SHRXQload,
|
||||||
|
|
@ -301,7 +301,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p := opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
|
p := opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
|
||||||
m := obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[0].Reg()}
|
m := obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[0].Reg()}
|
||||||
ssagen.AddAux(&m, v)
|
ssagen.AddAux(&m, v)
|
||||||
p.SetFrom3(m)
|
p.AddRestSource(m)
|
||||||
|
|
||||||
case ssa.OpAMD64SHLXLloadidx1, ssa.OpAMD64SHLXLloadidx4, ssa.OpAMD64SHLXLloadidx8,
|
case ssa.OpAMD64SHLXLloadidx1, ssa.OpAMD64SHLXLloadidx4, ssa.OpAMD64SHLXLloadidx8,
|
||||||
ssa.OpAMD64SHRXLloadidx1, ssa.OpAMD64SHRXLloadidx4, ssa.OpAMD64SHRXLloadidx8,
|
ssa.OpAMD64SHRXLloadidx1, ssa.OpAMD64SHRXLloadidx4, ssa.OpAMD64SHRXLloadidx8,
|
||||||
|
|
@ -313,7 +313,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
m := obj.Addr{Type: obj.TYPE_MEM}
|
m := obj.Addr{Type: obj.TYPE_MEM}
|
||||||
memIdx(&m, v)
|
memIdx(&m, v)
|
||||||
ssagen.AddAux(&m, v)
|
ssagen.AddAux(&m, v)
|
||||||
p.SetFrom3(m)
|
p.AddRestSource(m)
|
||||||
|
|
||||||
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.
|
||||||
|
|
@ -631,7 +631,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
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 = r
|
||||||
p.SetFrom3Reg(v.Args[0].Reg())
|
p.AddRestSourceReg(v.Args[0].Reg())
|
||||||
|
|
||||||
case ssa.OpAMD64ANDQconst:
|
case ssa.OpAMD64ANDQconst:
|
||||||
asm := v.Op.Asm()
|
asm := v.Op.Asm()
|
||||||
|
|
@ -1147,7 +1147,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
}
|
}
|
||||||
p.From.Offset = val
|
p.From.Offset = val
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.SetFrom3Reg(v.Args[0].Reg())
|
p.AddRestSourceReg(v.Args[0].Reg())
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
case ssa.OpAMD64POPCNTQ, ssa.OpAMD64POPCNTL,
|
case ssa.OpAMD64POPCNTQ, ssa.OpAMD64POPCNTL,
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,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_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = v.AuxInt >> 8
|
p.From.Offset = v.AuxInt >> 8
|
||||||
p.SetFrom3Const(v.AuxInt & 0xff)
|
p.AddRestSourceConst(v.AuxInt & 0xff)
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -302,7 +302,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p := s.Prog(arm.ABFC)
|
p := s.Prog(arm.ABFC)
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(width)
|
p.From.Offset = int64(width)
|
||||||
p.SetFrom3Const(int64(lsb))
|
p.AddRestSourceConst(int64(lsb))
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
break
|
break
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.Reg = ra
|
p.Reg = ra
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = rm
|
p.From.Reg = rm
|
||||||
p.SetFrom3Reg(rn)
|
p.AddRestSourceReg(rn)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = rt
|
p.To.Reg = rt
|
||||||
case ssa.OpARM64ADDconst,
|
case ssa.OpARM64ADDconst,
|
||||||
|
|
@ -309,7 +309,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_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = v.AuxInt
|
p.From.Offset = v.AuxInt
|
||||||
p.SetFrom3Reg(v.Args[0].Reg())
|
p.AddRestSourceReg(v.Args[0].Reg())
|
||||||
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 = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -558,7 +558,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_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = v.AuxInt >> 8
|
p.From.Offset = v.AuxInt >> 8
|
||||||
p.SetFrom3Const(v.AuxInt & 0xff)
|
p.AddRestSourceConst(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 = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -569,7 +569,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_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = v.AuxInt >> 8
|
p.From.Offset = v.AuxInt >> 8
|
||||||
p.SetFrom3Const(v.AuxInt & 0xff)
|
p.AddRestSourceConst(v.AuxInt & 0xff)
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -976,7 +976,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
condCode := condBits[ssa.Op(v.AuxInt)]
|
condCode := condBits[ssa.Op(v.AuxInt)]
|
||||||
p.From.Offset = int64(condCode)
|
p.From.Offset = int64(condCode)
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.SetFrom3Reg(r1)
|
p.AddRestSourceReg(r1)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
case ssa.OpARM64CSINC, ssa.OpARM64CSINV, ssa.OpARM64CSNEG:
|
case ssa.OpARM64CSINC, ssa.OpARM64CSINV, ssa.OpARM64CSNEG:
|
||||||
|
|
@ -985,7 +985,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
condCode := condBits[ssa.Op(v.AuxInt)]
|
condCode := condBits[ssa.Op(v.AuxInt)]
|
||||||
p.From.Offset = int64(condCode)
|
p.From.Offset = int64(condCode)
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.SetFrom3Reg(v.Args[1].Reg())
|
p.AddRestSourceReg(v.Args[1].Reg())
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
case ssa.OpARM64CSETM:
|
case ssa.OpARM64CSETM:
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
// If it is a Compare-and-Swap-Release operation, set the EH field with
|
// If it is a Compare-and-Swap-Release operation, set the EH field with
|
||||||
// the release hint.
|
// the release hint.
|
||||||
if v.AuxInt == 0 {
|
if v.AuxInt == 0 {
|
||||||
p0.SetFrom3Const(0)
|
p0.AddRestSourceConst(0)
|
||||||
}
|
}
|
||||||
// CMP reg1,reg2
|
// CMP reg1,reg2
|
||||||
p1 := s.Prog(cmp)
|
p1 := s.Prog(cmp)
|
||||||
|
|
@ -556,7 +556,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
// clrlslwi ra,rs,mb,sh will become rlwinm ra,rs,sh,mb-sh,31-sh as described in ISA
|
// clrlslwi ra,rs,mb,sh will become rlwinm ra,rs,sh,mb-sh,31-sh as described in ISA
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
|
||||||
p.SetFrom3Const(ssa.GetPPC64Shiftsh(shifts))
|
p.AddRestSourceConst(ssa.GetPPC64Shiftsh(shifts))
|
||||||
p.Reg = r1
|
p.Reg = r1
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = r
|
p.To.Reg = r
|
||||||
|
|
@ -568,7 +568,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
// clrlsldi ra,rs,mb,sh will become rldic ra,rs,sh,mb-sh
|
// clrlsldi ra,rs,mb,sh will become rldic ra,rs,sh,mb-sh
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
|
||||||
p.SetFrom3Const(ssa.GetPPC64Shiftsh(shifts))
|
p.AddRestSourceConst(ssa.GetPPC64Shiftsh(shifts))
|
||||||
p.Reg = r1
|
p.Reg = r1
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = r
|
p.To.Reg = r
|
||||||
|
|
@ -580,7 +580,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
shifts := v.AuxInt
|
shifts := v.AuxInt
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)}
|
||||||
p.SetFrom3Const(ssa.GetPPC64Shiftmb(shifts))
|
p.AddRestSourceConst(ssa.GetPPC64Shiftmb(shifts))
|
||||||
p.Reg = r1
|
p.Reg = r1
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = r
|
p.To.Reg = r
|
||||||
|
|
@ -628,8 +628,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(rot)}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(rot)}
|
||||||
p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
|
p.AddRestSourceArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
|
||||||
|
|
||||||
// Auxint holds mask
|
// Auxint holds mask
|
||||||
case ssa.OpPPC64RLWNM:
|
case ssa.OpPPC64RLWNM:
|
||||||
_, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
|
_, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
|
||||||
|
|
@ -637,7 +636,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()}
|
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()}
|
||||||
p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
|
p.AddRestSourceArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
|
||||||
|
|
||||||
case ssa.OpPPC64MADDLD:
|
case ssa.OpPPC64MADDLD:
|
||||||
r := v.Reg()
|
r := v.Reg()
|
||||||
|
|
@ -649,7 +648,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = r1
|
p.From.Reg = r1
|
||||||
p.Reg = r2
|
p.Reg = r2
|
||||||
p.SetFrom3Reg(r3)
|
p.AddRestSourceReg(r3)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = r
|
p.To.Reg = r
|
||||||
|
|
||||||
|
|
@ -663,7 +662,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = r1
|
p.From.Reg = r1
|
||||||
p.Reg = r3
|
p.Reg = r3
|
||||||
p.SetFrom3Reg(r2)
|
p.AddRestSourceReg(r2)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = r
|
p.To.Reg = r
|
||||||
|
|
||||||
|
|
@ -717,7 +716,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
|
|
||||||
case ssa.OpPPC64SUBCconst:
|
case ssa.OpPPC64SUBCconst:
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.SetFrom3Const(v.AuxInt)
|
p.AddRestSourceConst(v.AuxInt)
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = v.Args[0].Reg()
|
p.From.Reg = v.Args[0].Reg()
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
|
|
@ -725,7 +724,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
|
|
||||||
case ssa.OpPPC64SUBFCconst:
|
case ssa.OpPPC64SUBFCconst:
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.SetFrom3Const(v.AuxInt)
|
p.AddRestSourceConst(v.AuxInt)
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = v.Args[0].Reg()
|
p.From.Reg = v.Args[0].Reg()
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
|
|
@ -976,9 +975,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.SetFrom3Reg(ppc64.REG_R0)
|
|
||||||
if v.Op == ssa.OpPPC64ISEL {
|
if v.Op == ssa.OpPPC64ISEL {
|
||||||
p.SetFrom3Reg(v.Args[1].Reg())
|
p.AddRestSourceReg(v.Args[1].Reg())
|
||||||
|
} else {
|
||||||
|
p.AddRestSourceReg(ppc64.REG_R0)
|
||||||
}
|
}
|
||||||
// AuxInt values 4,5,6 implemented with reverse operand order from 0,1,2
|
// AuxInt values 4,5,6 implemented with reverse operand order from 0,1,2
|
||||||
if v.AuxInt > 3 {
|
if v.AuxInt > 3 {
|
||||||
|
|
@ -1867,7 +1867,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
pp.From.Offset = ppc64.BO_ALWAYS
|
pp.From.Offset = ppc64.BO_ALWAYS
|
||||||
pp.Reg = ppc64.REG_CR0LT // The preferred value if BI is ignored.
|
pp.Reg = ppc64.REG_CR0LT // The preferred value if BI is ignored.
|
||||||
pp.To.Reg = ppc64.REG_LR
|
pp.To.Reg = ppc64.REG_LR
|
||||||
pp.SetFrom3Const(1)
|
pp.AddRestSourceConst(1)
|
||||||
|
|
||||||
if ppc64.NeedTOCpointer(base.Ctxt) {
|
if ppc64.NeedTOCpointer(base.Ctxt) {
|
||||||
// When compiling Go into PIC, the function we just
|
// When compiling Go into PIC, the function we just
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = r2
|
p.From.Reg = r2
|
||||||
p.Reg = r1
|
p.Reg = r1
|
||||||
p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_REG, Reg: r3}})
|
p.AddRestSource(obj.Addr{Type: obj.TYPE_REG, Reg: r3})
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = r
|
p.To.Reg = r
|
||||||
case ssa.OpRISCV64FSQRTS, ssa.OpRISCV64FNEGS, ssa.OpRISCV64FABSD, ssa.OpRISCV64FSQRTD, ssa.OpRISCV64FNEGD,
|
case ssa.OpRISCV64FSQRTS, ssa.OpRISCV64FNEGS, ssa.OpRISCV64FABSD, ssa.OpRISCV64FSQRTD, ssa.OpRISCV64FNEGD,
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
i := v.Aux.(s390x.RotateParams)
|
i := v.Aux.(s390x.RotateParams)
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(i.Start)}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(i.Start)}
|
||||||
p.SetRestArgs([]obj.Addr{
|
p.AddRestSourceArgs([]obj.Addr{
|
||||||
{Type: obj.TYPE_CONST, Offset: int64(i.End)},
|
{Type: obj.TYPE_CONST, Offset: int64(i.End)},
|
||||||
{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},
|
||||||
|
|
@ -196,7 +196,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
i := v.Aux.(s390x.RotateParams)
|
i := v.Aux.(s390x.RotateParams)
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(i.Start)}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(i.Start)}
|
||||||
p.SetRestArgs([]obj.Addr{
|
p.AddRestSourceArgs([]obj.Addr{
|
||||||
{Type: obj.TYPE_CONST, Offset: int64(i.End)},
|
{Type: obj.TYPE_CONST, Offset: int64(i.End)},
|
||||||
{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},
|
||||||
|
|
@ -627,7 +627,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p := s.Prog(s390x.AMVC)
|
p := s.Prog(s390x.AMVC)
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = vo.Val64()
|
p.From.Offset = vo.Val64()
|
||||||
p.SetFrom3(obj.Addr{
|
p.AddRestSource(obj.Addr{
|
||||||
Type: obj.TYPE_MEM,
|
Type: obj.TYPE_MEM,
|
||||||
Reg: v.Args[1].Reg(),
|
Reg: v.Args[1].Reg(),
|
||||||
Offset: vo.Off64(),
|
Offset: vo.Off64(),
|
||||||
|
|
@ -664,7 +664,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
mvc := s.Prog(s390x.AMVC)
|
mvc := s.Prog(s390x.AMVC)
|
||||||
mvc.From.Type = obj.TYPE_CONST
|
mvc.From.Type = obj.TYPE_CONST
|
||||||
mvc.From.Offset = 256
|
mvc.From.Offset = 256
|
||||||
mvc.SetFrom3(obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[1].Reg()})
|
mvc.AddRestSource(obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[1].Reg()})
|
||||||
mvc.To.Type = obj.TYPE_MEM
|
mvc.To.Type = obj.TYPE_MEM
|
||||||
mvc.To.Reg = v.Args[0].Reg()
|
mvc.To.Reg = v.Args[0].Reg()
|
||||||
|
|
||||||
|
|
@ -691,7 +691,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
mvc := s.Prog(s390x.AMVC)
|
mvc := s.Prog(s390x.AMVC)
|
||||||
mvc.From.Type = obj.TYPE_CONST
|
mvc.From.Type = obj.TYPE_CONST
|
||||||
mvc.From.Offset = v.AuxInt
|
mvc.From.Offset = v.AuxInt
|
||||||
mvc.SetFrom3(obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[1].Reg()})
|
mvc.AddRestSource(obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[1].Reg()})
|
||||||
mvc.To.Type = obj.TYPE_MEM
|
mvc.To.Type = obj.TYPE_MEM
|
||||||
mvc.To.Reg = v.Args[0].Reg()
|
mvc.To.Reg = v.Args[0].Reg()
|
||||||
}
|
}
|
||||||
|
|
@ -902,7 +902,7 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(s390x.NotEqual & s390x.NotUnordered) // unordered is not possible
|
p.From.Offset = int64(s390x.NotEqual & s390x.NotUnordered) // unordered is not possible
|
||||||
p.Reg = s390x.REG_R3
|
p.Reg = s390x.REG_R3
|
||||||
p.SetFrom3Const(0)
|
p.AddRestSourceConst(0)
|
||||||
if b.Succs[0].Block() != next {
|
if b.Succs[0].Block() != next {
|
||||||
s.Br(s390x.ABR, b.Succs[0].Block())
|
s.Br(s390x.ABR, b.Succs[0].Block())
|
||||||
}
|
}
|
||||||
|
|
@ -939,17 +939,17 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
|
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
|
||||||
p.Reg = b.Controls[0].Reg()
|
p.Reg = b.Controls[0].Reg()
|
||||||
p.SetFrom3Reg(b.Controls[1].Reg())
|
p.AddRestSourceReg(b.Controls[1].Reg())
|
||||||
case ssa.BlockS390XCGIJ, ssa.BlockS390XCIJ:
|
case ssa.BlockS390XCGIJ, ssa.BlockS390XCIJ:
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
|
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
|
||||||
p.Reg = b.Controls[0].Reg()
|
p.Reg = b.Controls[0].Reg()
|
||||||
p.SetFrom3Const(int64(int8(b.AuxInt)))
|
p.AddRestSourceConst(int64(int8(b.AuxInt)))
|
||||||
case ssa.BlockS390XCLGIJ, ssa.BlockS390XCLIJ:
|
case ssa.BlockS390XCLGIJ, ssa.BlockS390XCLIJ:
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
|
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
|
||||||
p.Reg = b.Controls[0].Reg()
|
p.Reg = b.Controls[0].Reg()
|
||||||
p.SetFrom3Const(int64(uint8(b.AuxInt)))
|
p.AddRestSourceConst(int64(uint8(b.AuxInt)))
|
||||||
default:
|
default:
|
||||||
b.Fatalf("branch not implemented: %s", b.LongString())
|
b.Fatalf("branch not implemented: %s", b.LongString())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -345,7 +345,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
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 = r
|
||||||
p.SetFrom3Reg(v.Args[0].Reg())
|
p.AddRestSourceReg(v.Args[0].Reg())
|
||||||
|
|
||||||
case ssa.Op386SUBLconst,
|
case ssa.Op386SUBLconst,
|
||||||
ssa.Op386ADCLconst,
|
ssa.Op386ADCLconst,
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ type Prog struct {
|
||||||
Ctxt *Link // linker context
|
Ctxt *Link // linker context
|
||||||
Link *Prog // next Prog in linked list
|
Link *Prog // next Prog in linked list
|
||||||
From Addr // first source operand
|
From Addr // first source operand
|
||||||
RestArgs []AddrPos // can pack any operands that not fit into {Prog.From, Prog.To}
|
RestArgs []AddrPos // can pack any operands that not fit into {Prog.From, Prog.To}, same kinds of operands are saved in order
|
||||||
To Addr // destination operand (second is RegTo2 below)
|
To Addr // destination operand (second is RegTo2 below)
|
||||||
Pool *Prog // constant pool entry, for arm,arm64 back ends
|
Pool *Prog // constant pool entry, for arm,arm64 back ends
|
||||||
Forwd *Prog // for x86 back end
|
Forwd *Prog // for x86 back end
|
||||||
|
|
@ -336,69 +336,63 @@ const (
|
||||||
|
|
||||||
// From3Type returns p.GetFrom3().Type, or TYPE_NONE when
|
// From3Type returns p.GetFrom3().Type, or TYPE_NONE when
|
||||||
// p.GetFrom3() returns nil.
|
// p.GetFrom3() returns nil.
|
||||||
//
|
|
||||||
// Deprecated: for the same reasons as Prog.GetFrom3.
|
|
||||||
func (p *Prog) From3Type() AddrType {
|
func (p *Prog) From3Type() AddrType {
|
||||||
if p.RestArgs == nil {
|
from3 := p.GetFrom3()
|
||||||
|
if from3 == nil {
|
||||||
return TYPE_NONE
|
return TYPE_NONE
|
||||||
}
|
}
|
||||||
return p.RestArgs[0].Type
|
return from3.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFrom3 returns second source operand (the first is Prog.From).
|
// GetFrom3 returns second source operand (the first is Prog.From).
|
||||||
|
// The same kinds of operands are saved in order so GetFrom3 actually
|
||||||
|
// return the first source operand in p.RestArgs.
|
||||||
// In combination with Prog.From and Prog.To it makes common 3 operand
|
// In combination with Prog.From and Prog.To it makes common 3 operand
|
||||||
// case easier to use.
|
// case easier to use.
|
||||||
//
|
|
||||||
// Should be used only when RestArgs is set with SetFrom3.
|
|
||||||
//
|
|
||||||
// Deprecated: better use RestArgs directly or define backend-specific getters.
|
|
||||||
// Introduced to simplify transition to []Addr.
|
|
||||||
// Usage of this is discouraged due to fragility and lack of guarantees.
|
|
||||||
func (p *Prog) GetFrom3() *Addr {
|
func (p *Prog) GetFrom3() *Addr {
|
||||||
if p.RestArgs == nil {
|
for i := range p.RestArgs {
|
||||||
return nil
|
if p.RestArgs[i].Pos == Source {
|
||||||
|
return &p.RestArgs[i].Addr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &p.RestArgs[0].Addr
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFrom3 assigns []Args{{a, 0}} to p.RestArgs.
|
// AddRestSource assigns []Args{{a, Source}} to p.RestArgs.
|
||||||
// In pair with Prog.GetFrom3 it can help in emulation of Prog.From3.
|
func (p *Prog) AddRestSource(a Addr) {
|
||||||
//
|
p.RestArgs = append(p.RestArgs, AddrPos{a, Source})
|
||||||
// Deprecated: for the same reasons as Prog.GetFrom3.
|
|
||||||
func (p *Prog) SetFrom3(a Addr) {
|
|
||||||
p.RestArgs = []AddrPos{{a, Source}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFrom3Reg calls p.SetFrom3 with a register Addr containing reg.
|
// AddRestSourceReg calls p.AddRestSource with a register Addr containing reg.
|
||||||
//
|
func (p *Prog) AddRestSourceReg(reg int16) {
|
||||||
// Deprecated: for the same reasons as Prog.GetFrom3.
|
p.AddRestSource(Addr{Type: TYPE_REG, Reg: reg})
|
||||||
func (p *Prog) SetFrom3Reg(reg int16) {
|
|
||||||
p.SetFrom3(Addr{Type: TYPE_REG, Reg: reg})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFrom3Const calls p.SetFrom3 with a const Addr containing x.
|
// AddRestSourceConst calls p.AddRestSource with a const Addr containing off.
|
||||||
//
|
func (p *Prog) AddRestSourceConst(off int64) {
|
||||||
// Deprecated: for the same reasons as Prog.GetFrom3.
|
p.AddRestSource(Addr{Type: TYPE_CONST, Offset: off})
|
||||||
func (p *Prog) SetFrom3Const(off int64) {
|
|
||||||
p.SetFrom3(Addr{Type: TYPE_CONST, Offset: off})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTo2 assigns []Args{{a, 1}} to p.RestArgs when the second destination
|
// AddRestDest assigns []Args{{a, Destination}} to p.RestArgs when the second destination
|
||||||
// operand does not fit into prog.RegTo2.
|
// operand does not fit into prog.RegTo2.
|
||||||
func (p *Prog) SetTo2(a Addr) {
|
func (p *Prog) AddRestDest(a Addr) {
|
||||||
p.RestArgs = []AddrPos{{a, Destination}}
|
p.RestArgs = append(p.RestArgs, AddrPos{a, Destination})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTo2 returns the second destination operand.
|
// GetTo2 returns the second destination operand.
|
||||||
|
// The same kinds of operands are saved in order so GetTo2 actually
|
||||||
|
// return the first destination operand in Prog.RestArgs[]
|
||||||
func (p *Prog) GetTo2() *Addr {
|
func (p *Prog) GetTo2() *Addr {
|
||||||
if p.RestArgs == nil {
|
for i := range p.RestArgs {
|
||||||
return nil
|
if p.RestArgs[i].Pos == Destination {
|
||||||
|
return &p.RestArgs[i].Addr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &p.RestArgs[0].Addr
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRestArgs assigns more than one source operands to p.RestArgs.
|
// AddRestSourceArgs assigns more than one source operands to p.RestArgs.
|
||||||
func (p *Prog) SetRestArgs(args []Addr) {
|
func (p *Prog) AddRestSourceArgs(args []Addr) {
|
||||||
for i := range args {
|
for i := range args {
|
||||||
p.RestArgs = append(p.RestArgs, AddrPos{args[i], Source})
|
p.RestArgs = append(p.RestArgs, AddrPos{args[i], Source})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,8 @@ func checkaddr(ctxt *Link, p *Prog, a *Addr) {
|
||||||
func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
|
func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
|
||||||
for p := sym.Func().Text; p != nil; p = p.Link {
|
for p := sym.Func().Text; p != nil; p = p.Link {
|
||||||
checkaddr(ctxt, p, &p.From)
|
checkaddr(ctxt, p, &p.From)
|
||||||
if p.GetFrom3() != nil {
|
for _, v := range p.RestArgs {
|
||||||
checkaddr(ctxt, p, p.GetFrom3())
|
checkaddr(ctxt, p, &v.Addr)
|
||||||
}
|
}
|
||||||
checkaddr(ctxt, p, &p.To)
|
checkaddr(ctxt, p, &p.To)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -665,7 +665,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
|
|
||||||
p.As = AAUIPC
|
p.As = AAUIPC
|
||||||
p.Mark = (p.Mark &^ NEED_CALL_RELOC) | NEED_PCREL_ITYPE_RELOC
|
p.Mark = (p.Mark &^ NEED_CALL_RELOC) | NEED_PCREL_ITYPE_RELOC
|
||||||
p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: p.To.Offset, Sym: p.To.Sym})
|
p.AddRestSource(obj.Addr{Type: obj.TYPE_CONST, Offset: p.To.Offset, Sym: p.To.Sym})
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0}
|
||||||
p.Reg = obj.REG_NONE
|
p.Reg = obj.REG_NONE
|
||||||
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
|
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
|
||||||
|
|
|
||||||
|
|
@ -499,7 +499,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||||
p2.From = p.From
|
p2.From = p.From
|
||||||
p2.To = p.To
|
p2.To = p.To
|
||||||
if from3 := p.GetFrom3(); from3 != nil {
|
if from3 := p.GetFrom3(); from3 != nil {
|
||||||
p2.SetFrom3(*from3)
|
p2.AddRestSource(*from3)
|
||||||
}
|
}
|
||||||
if p.From.Name == obj.NAME_EXTERN {
|
if p.From.Name == obj.NAME_EXTERN {
|
||||||
p2.From.Reg = reg
|
p2.From.Reg = reg
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue