prog.Reg = p.getRegister(prog, op, &a[1])
} else {
// Compare register with immediate and jump.
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
}
break
}
// 4-operand compare-and-branch.
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
- prog.SetFrom3(a[2])
+ prog.AddRestSource(a[2])
target = &a[3]
break
}
if arch.IsARMBFX(op) {
// a[0] and a[1] must be constants, a[2] must be a register
prog.From = a[0]
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
prog.To = a[2]
break
}
prog.To = a[2]
case sys.AMD64:
prog.From = a[0]
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
prog.To = a[2]
case sys.ARM64:
switch {
case arch.IsARM64TBL(op):
// one of its inputs does not fit into prog.Reg.
prog.From = a[0]
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
prog.To = a[2]
case arch.IsARM64CASP(op):
prog.From = a[0]
}
// 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.
- prog.SetTo2(a[2])
+ prog.AddRestDest(a[2])
default:
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
}
case sys.I386:
prog.From = a[0]
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
prog.To = a[2]
case sys.PPC64:
if arch.IsPPC64CMP(op) {
prog.To = a[2]
// If the second argument is not a register argument, it must be
- // passed RestArgs/SetFrom3
+ // passed RestArgs/AddRestSource
switch a[1].Type {
case obj.TYPE_REG:
prog.Reg = p.getRegister(prog, op, &a[1])
default:
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
}
case sys.RISCV64:
// RISCV64 instructions with one input and two outputs.
if a[1].Type == obj.TYPE_REG {
prog.Reg = p.getRegister(prog, op, &a[1])
} else {
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
}
prog.To = a[2]
default:
if arch.IsARMBFX(op) {
// a[0] and a[1] must be constants, a[2] and a[3] must be registers
prog.From = a[0]
- prog.SetFrom3(a[1])
+ prog.AddRestSource(a[1])
prog.Reg = p.getRegister(prog, op, &a[2])
prog.To = a[3]
break
}
if p.arch.Family == sys.AMD64 {
prog.From = a[0]
- prog.SetRestArgs([]obj.Addr{a[1], a[2]})
+ prog.AddRestSourceArgs([]obj.Addr{a[1], a[2]})
prog.To = a[3]
break
}
if p.arch.Family == sys.ARM64 {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
- prog.SetFrom3(a[2])
+ prog.AddRestSource(a[2])
prog.To = a[3]
break
}
prog.From = a[0]
prog.To = a[3]
// 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 {
prog.Reg = p.getRegister(prog, op, &a[1])
- prog.SetRestArgs([]obj.Addr{a[2]})
+ prog.AddRestSource(a[2])
} else {
// 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
}
if p.arch.Family == sys.RISCV64 {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
- prog.SetRestArgs([]obj.Addr{a[2]})
+ prog.AddRestSource(a[2])
prog.To = a[3]
break
}
}
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
- prog.SetFrom3(a[2])
+ prog.AddRestSource(a[2])
prog.To = a[3]
break
}
prog.From = a[0]
// Second arg is always a register type on ppc64.
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]
break
}
if p.arch.Family == sys.AMD64 {
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]
break
}
if p.arch.Family == sys.S390X {
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]
break
}
prog.From = a[0]
// Second arg is always a register type on ppc64.
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]
break
}
p := s.Prog(v.Op.Asm())
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.SetFrom3Reg(v.Args[1].Reg())
+ p.AddRestSourceReg(v.Args[1].Reg())
case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL:
r := v.Reg()
r1 := v.Args[0].Reg()
p.From.Reg = bits
p.To.Type = obj.TYPE_REG
p.To.Reg = lo
- p.SetFrom3Reg(hi)
+ p.AddRestSourceReg(hi)
case ssa.OpAMD64BLSIQ, ssa.OpAMD64BLSIL,
ssa.OpAMD64BLSMSKQ, ssa.OpAMD64BLSMSKL,
p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
- p.SetFrom3Reg(v.Args[1].Reg())
+ p.AddRestSourceReg(v.Args[1].Reg())
case ssa.OpAMD64SARXL, ssa.OpAMD64SARXQ,
ssa.OpAMD64SHLXL, ssa.OpAMD64SHLXQ,
ssa.OpAMD64SHRXL, ssa.OpAMD64SHRXQ:
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,
ssa.OpAMD64SHRXLload, ssa.OpAMD64SHRXQload,
p := opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
m := obj.Addr{Type: obj.TYPE_MEM, Reg: v.Args[0].Reg()}
ssagen.AddAux(&m, v)
- p.SetFrom3(m)
+ p.AddRestSource(m)
case ssa.OpAMD64SHLXLloadidx1, ssa.OpAMD64SHLXLloadidx4, ssa.OpAMD64SHLXLloadidx8,
ssa.OpAMD64SHRXLloadidx1, ssa.OpAMD64SHRXLloadidx4, ssa.OpAMD64SHRXLloadidx8,
m := obj.Addr{Type: obj.TYPE_MEM}
memIdx(&m, v)
ssagen.AddAux(&m, v)
- p.SetFrom3(m)
+ p.AddRestSource(m)
case ssa.OpAMD64DIVQU, ssa.OpAMD64DIVLU, ssa.OpAMD64DIVWU:
// Arg[0] (the dividend) is in AX.
p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG
p.To.Reg = r
- p.SetFrom3Reg(v.Args[0].Reg())
+ p.AddRestSourceReg(v.Args[0].Reg())
case ssa.OpAMD64ANDQconst:
asm := v.Op.Asm()
}
p.From.Offset = val
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.Reg = v.Reg()
case ssa.OpAMD64POPCNTQ, ssa.OpAMD64POPCNTL,
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt >> 8
- p.SetFrom3Const(v.AuxInt & 0xff)
+ p.AddRestSourceConst(v.AuxInt & 0xff)
p.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
p := s.Prog(arm.ABFC)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(width)
- p.SetFrom3Const(int64(lsb))
+ p.AddRestSourceConst(int64(lsb))
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
break
p.Reg = ra
p.From.Type = obj.TYPE_REG
p.From.Reg = rm
- p.SetFrom3Reg(rn)
+ p.AddRestSourceReg(rn)
p.To.Type = obj.TYPE_REG
p.To.Reg = rt
case ssa.OpARM64ADDconst,
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt
- p.SetFrom3Reg(v.Args[0].Reg())
+ p.AddRestSourceReg(v.Args[0].Reg())
p.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt >> 8
- p.SetFrom3Const(v.AuxInt & 0xff)
+ p.AddRestSourceConst(v.AuxInt & 0xff)
p.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt >> 8
- p.SetFrom3Const(v.AuxInt & 0xff)
+ p.AddRestSourceConst(v.AuxInt & 0xff)
p.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
condCode := condBits[ssa.Op(v.AuxInt)]
p.From.Offset = int64(condCode)
p.Reg = v.Args[0].Reg()
- p.SetFrom3Reg(r1)
+ p.AddRestSourceReg(r1)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpARM64CSINC, ssa.OpARM64CSINV, ssa.OpARM64CSNEG:
condCode := condBits[ssa.Op(v.AuxInt)]
p.From.Offset = int64(condCode)
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.Reg = v.Reg()
case ssa.OpARM64CSETM:
// If it is a Compare-and-Swap-Release operation, set the EH field with
// the release hint.
if v.AuxInt == 0 {
- p0.SetFrom3Const(0)
+ p0.AddRestSourceConst(0)
}
// CMP reg1,reg2
p1 := s.Prog(cmp)
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
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.To.Type = obj.TYPE_REG
p.To.Reg = r
p := s.Prog(v.Op.Asm())
// 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.SetFrom3Const(ssa.GetPPC64Shiftsh(shifts))
+ p.AddRestSourceConst(ssa.GetPPC64Shiftsh(shifts))
p.Reg = r1
p.To.Type = obj.TYPE_REG
p.To.Reg = r
shifts := v.AuxInt
p := s.Prog(v.Op.Asm())
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.To.Type = obj.TYPE_REG
p.To.Reg = r
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
p.Reg = v.Args[0].Reg()
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
case ssa.OpPPC64RLWNM:
_, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
p.Reg = v.Args[0].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:
r := v.Reg()
p.From.Type = obj.TYPE_REG
p.From.Reg = r1
p.Reg = r2
- p.SetFrom3Reg(r3)
+ p.AddRestSourceReg(r3)
p.To.Type = obj.TYPE_REG
p.To.Reg = r
p.From.Type = obj.TYPE_REG
p.From.Reg = r1
p.Reg = r3
- p.SetFrom3Reg(r2)
+ p.AddRestSourceReg(r2)
p.To.Type = obj.TYPE_REG
p.To.Reg = r
case ssa.OpPPC64SUBCconst:
p := s.Prog(v.Op.Asm())
- p.SetFrom3Const(v.AuxInt)
+ p.AddRestSourceConst(v.AuxInt)
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
case ssa.OpPPC64SUBFCconst:
p := s.Prog(v.Op.Asm())
- p.SetFrom3Const(v.AuxInt)
+ p.AddRestSourceConst(v.AuxInt)
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p := s.Prog(v.Op.Asm())
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
p.Reg = v.Args[0].Reg()
- p.SetFrom3Reg(ppc64.REG_R0)
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
if v.AuxInt > 3 {
pp.From.Offset = ppc64.BO_ALWAYS
pp.Reg = ppc64.REG_CR0LT // The preferred value if BI is ignored.
pp.To.Reg = ppc64.REG_LR
- pp.SetFrom3Const(1)
+ pp.AddRestSourceConst(1)
if ppc64.NeedTOCpointer(base.Ctxt) {
// When compiling Go into PIC, the function we just
p.From.Type = obj.TYPE_REG
p.From.Reg = r2
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.Reg = r
case ssa.OpRISCV64FSQRTS, ssa.OpRISCV64FNEGS, ssa.OpRISCV64FABSD, ssa.OpRISCV64FSQRTD, ssa.OpRISCV64FNEGD,
i := v.Aux.(s390x.RotateParams)
p := s.Prog(v.Op.Asm())
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.Amount)},
{Type: obj.TYPE_REG, Reg: r2},
i := v.Aux.(s390x.RotateParams)
p := s.Prog(v.Op.Asm())
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.Amount)},
{Type: obj.TYPE_REG, Reg: r2},
p := s.Prog(s390x.AMVC)
p.From.Type = obj.TYPE_CONST
p.From.Offset = vo.Val64()
- p.SetFrom3(obj.Addr{
+ p.AddRestSource(obj.Addr{
Type: obj.TYPE_MEM,
Reg: v.Args[1].Reg(),
Offset: vo.Off64(),
mvc := s.Prog(s390x.AMVC)
mvc.From.Type = obj.TYPE_CONST
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.Reg = v.Args[0].Reg()
mvc := s.Prog(s390x.AMVC)
mvc.From.Type = obj.TYPE_CONST
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.Reg = v.Args[0].Reg()
}
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(s390x.NotEqual & s390x.NotUnordered) // unordered is not possible
p.Reg = s390x.REG_R3
- p.SetFrom3Const(0)
+ p.AddRestSourceConst(0)
if b.Succs[0].Block() != next {
s.Br(s390x.ABR, b.Succs[0].Block())
}
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
p.Reg = b.Controls[0].Reg()
- p.SetFrom3Reg(b.Controls[1].Reg())
+ p.AddRestSourceReg(b.Controls[1].Reg())
case ssa.BlockS390XCGIJ, ssa.BlockS390XCIJ:
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
p.Reg = b.Controls[0].Reg()
- p.SetFrom3Const(int64(int8(b.AuxInt)))
+ p.AddRestSourceConst(int64(int8(b.AuxInt)))
case ssa.BlockS390XCLGIJ, ssa.BlockS390XCLIJ:
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible
p.Reg = b.Controls[0].Reg()
- p.SetFrom3Const(int64(uint8(b.AuxInt)))
+ p.AddRestSourceConst(int64(uint8(b.AuxInt)))
default:
b.Fatalf("branch not implemented: %s", b.LongString())
}
p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG
p.To.Reg = r
- p.SetFrom3Reg(v.Args[0].Reg())
+ p.AddRestSourceReg(v.Args[0].Reg())
case ssa.Op386SUBLconst,
ssa.Op386ADCLconst,
Ctxt *Link // linker context
Link *Prog // next Prog in linked list
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)
Pool *Prog // constant pool entry, for arm,arm64 back ends
Forwd *Prog // for x86 back end
// From3Type returns p.GetFrom3().Type, or TYPE_NONE when
// p.GetFrom3() returns nil.
-//
-// Deprecated: for the same reasons as Prog.GetFrom3.
func (p *Prog) From3Type() AddrType {
- if p.RestArgs == nil {
+ from3 := p.GetFrom3()
+ if from3 == nil {
return TYPE_NONE
}
- return p.RestArgs[0].Type
+ return from3.Type
}
// 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
// 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 {
- if p.RestArgs == nil {
- return nil
+ for i := range p.RestArgs {
+ 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.
-// In pair with Prog.GetFrom3 it can help in emulation of Prog.From3.
-//
-// Deprecated: for the same reasons as Prog.GetFrom3.
-func (p *Prog) SetFrom3(a Addr) {
- p.RestArgs = []AddrPos{{a, Source}}
+// AddRestSource assigns []Args{{a, Source}} to p.RestArgs.
+func (p *Prog) AddRestSource(a Addr) {
+ p.RestArgs = append(p.RestArgs, AddrPos{a, Source})
}
-// SetFrom3Reg calls p.SetFrom3 with a register Addr containing reg.
-//
-// Deprecated: for the same reasons as Prog.GetFrom3.
-func (p *Prog) SetFrom3Reg(reg int16) {
- p.SetFrom3(Addr{Type: TYPE_REG, Reg: reg})
+// AddRestSourceReg calls p.AddRestSource with a register Addr containing reg.
+func (p *Prog) AddRestSourceReg(reg int16) {
+ p.AddRestSource(Addr{Type: TYPE_REG, Reg: reg})
}
-// SetFrom3Const calls p.SetFrom3 with a const Addr containing x.
-//
-// Deprecated: for the same reasons as Prog.GetFrom3.
-func (p *Prog) SetFrom3Const(off int64) {
- p.SetFrom3(Addr{Type: TYPE_CONST, Offset: off})
+// AddRestSourceConst calls p.AddRestSource with a const Addr containing off.
+func (p *Prog) AddRestSourceConst(off int64) {
+ p.AddRestSource(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.
-func (p *Prog) SetTo2(a Addr) {
- p.RestArgs = []AddrPos{{a, Destination}}
+func (p *Prog) AddRestDest(a Addr) {
+ p.RestArgs = append(p.RestArgs, AddrPos{a, Destination})
}
// 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 {
- if p.RestArgs == nil {
- return nil
+ for i := range p.RestArgs {
+ 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.
-func (p *Prog) SetRestArgs(args []Addr) {
+// AddRestSourceArgs assigns more than one source operands to p.RestArgs.
+func (p *Prog) AddRestSourceArgs(args []Addr) {
for i := range args {
p.RestArgs = append(p.RestArgs, AddrPos{args[i], Source})
}
func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
for p := sym.Func().Text; p != nil; p = p.Link {
checkaddr(ctxt, p, &p.From)
- if p.GetFrom3() != nil {
- checkaddr(ctxt, p, p.GetFrom3())
+ for _, v := range p.RestArgs {
+ checkaddr(ctxt, p, &v.Addr)
}
checkaddr(ctxt, p, &p.To)
p.As = AAUIPC
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.Reg = obj.REG_NONE
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
p2.From = p.From
p2.To = p.To
if from3 := p.GetFrom3(); from3 != nil {
- p2.SetFrom3(*from3)
+ p2.AddRestSource(*from3)
}
if p.From.Name == obj.NAME_EXTERN {
p2.From.Reg = reg